mirror of
https://github.com/EQEmu/Server.git
synced 2026-05-22 20:33:01 +00:00
Compare commits
71 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 86fddc4d3b | |||
| 570234a6ee | |||
| 8e4bb3b0fe | |||
| 385f3d0394 | |||
| 6186ec8e12 | |||
| aa749f27dc | |||
| 598a4a6878 | |||
| 6064ca95f9 | |||
| 3448dd1a9e | |||
| dd6d1d5511 | |||
| b8dd81de66 | |||
| 31158ed03d | |||
| fa5dedec11 | |||
| 774e9becbd | |||
| 5cbd741358 | |||
| b0274e34e2 | |||
| adc740da5a | |||
| 240b066f34 | |||
| fffe59c52e | |||
| 7ad2ead1be | |||
| f2114c7611 | |||
| cb009aba7c | |||
| 9df7e9e1f3 | |||
| 7f6997baf4 | |||
| 6edb4c2b37 | |||
| 910ee66fce | |||
| f662141f86 | |||
| c5498c66fa | |||
| 3df5b6da57 | |||
| e47ad72b1c | |||
| f3af295f34 | |||
| 9eb41c7b0d | |||
| ee8b950df1 | |||
| 29b4498534 | |||
| 91ecf759e3 | |||
| 5a7a2b0aef | |||
| 45b83feb99 | |||
| f4621bd5c0 | |||
| 06f7f6b483 | |||
| 509babc2d1 | |||
| ca86763c2b | |||
| a602640188 | |||
| b9e6a1f5eb | |||
| 119e0bb0ac | |||
| 34913c2046 | |||
| c6d8b7e337 | |||
| 2ed960d733 | |||
| dd88d0096b | |||
| 7c3cfd43de | |||
| 4e1fcfb7e5 | |||
| 379ecc655c | |||
| ae30d8b257 | |||
| 40b555a55b | |||
| 002f5e3bcc | |||
| 780789fbad | |||
| 927580b983 | |||
| 7359eb01d4 | |||
| da6d7538b0 | |||
| 69e90aac0a | |||
| 2dff51a4db | |||
| e442d682cd | |||
| 0e0638f11d | |||
| 5ad7b84415 | |||
| e0bc0e2e5c | |||
| 4109b0b88d | |||
| 80892f1d4d | |||
| 9e3e8dbfa6 | |||
| 74f07f8e19 | |||
| f866fd59d9 | |||
| d6da569fc6 | |||
| 7ec0994433 |
@@ -35,8 +35,3 @@ Build_64/
|
||||
build_64/
|
||||
log/
|
||||
logs/
|
||||
|
||||
submodules/
|
||||
.idea/
|
||||
cmake-build-debug
|
||||
EQEmu.cbp
|
||||
+7
-7
@@ -257,7 +257,7 @@ OPTION(EQEMU_BUILD_LOGIN "Build the login server." OFF)
|
||||
OPTION(EQEMU_BUILD_TESTS "Build utility tests." OFF)
|
||||
OPTION(EQEMU_BUILD_PERL "Build Perl parser." ON)
|
||||
OPTION(EQEMU_BUILD_LUA "Build Lua parser." ON)
|
||||
OPTION(EQEMU_BUILD_CLIENT_FILES "Build Client Import/Export Data Programs." ON)
|
||||
OPTION(EQEMU_BUILD_CLIENT_FILES "Build Client Inport/Export Data Programs." ON)
|
||||
|
||||
#C++11 stuff
|
||||
IF(NOT MSVC)
|
||||
@@ -265,6 +265,8 @@ IF(NOT MSVC)
|
||||
IF("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
|
||||
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-reserved-user-defined-literal")
|
||||
ENDIF()
|
||||
|
||||
ADD_DEFINITIONS(-D__STDC_CONSTANT_MACROS)
|
||||
ENDIF(NOT MSVC)
|
||||
|
||||
#Various definitions
|
||||
@@ -323,7 +325,7 @@ IF(EQEMU_BUILD_LUA)
|
||||
SET(BOOST_ROOT "${CMAKE_CURRENT_SOURCE_DIR}/dependencies/boost")
|
||||
|
||||
FIND_PACKAGE(Boost REQUIRED)
|
||||
INCLUDE_DIRECTORIES(SYSTEM "${LUA_INCLUDE_DIR}" "${Boost_INCLUDE_DIRS}" "luabind")
|
||||
INCLUDE_DIRECTORIES(SYSTEM "${LUA_INCLUDE_DIR}" "${Boost_INCLUDE_DIRS}" "${CMAKE_CURRENT_SOURCE_DIR}/dependencies/luabind")
|
||||
|
||||
OPTION(EQEMU_SANITIZE_LUA_LIBS "Sanitize Lua Libraries (Remove OS and IO standard libraries from being able to run)." ON)
|
||||
IF(EQEMU_SANITIZE_LUA_LIBS)
|
||||
@@ -331,11 +333,7 @@ IF(EQEMU_BUILD_LUA)
|
||||
ENDIF(EQEMU_SANITIZE_LUA_LIBS)
|
||||
ENDIF(EQEMU_BUILD_LUA)
|
||||
|
||||
INCLUDE_DIRECTORIES(SYSTEM "${ZLIB_INCLUDE_DIRS}" "${MySQL_INCLUDE_DIR}" "${CMAKE_CURRENT_SOURCE_DIR}/common/glm")
|
||||
|
||||
IF(EQEMU_BUILD_LUA)
|
||||
ADD_SUBDIRECTORY(luabind)
|
||||
ENDIF(EQEMU_BUILD_LUA)
|
||||
INCLUDE_DIRECTORIES(SYSTEM "${ZLIB_INCLUDE_DIRS}" "${MySQL_INCLUDE_DIR}" "${CMAKE_CURRENT_SOURCE_DIR}/common/glm" "${CMAKE_CURRENT_SOURCE_DIR}/dependencies/libwebsockets" "${CMAKE_CURRENT_SOURCE_DIR}/common/rapidjson")
|
||||
|
||||
IF(EQEMU_BUILD_SERVER OR EQEMU_BUILD_LOGIN OR EQEMU_BUILD_TESTS)
|
||||
ADD_SUBDIRECTORY(common)
|
||||
@@ -347,6 +345,8 @@ IF(EQEMU_BUILD_SERVER)
|
||||
ADD_SUBDIRECTORY(ucs)
|
||||
ADD_SUBDIRECTORY(queryserv)
|
||||
ADD_SUBDIRECTORY(eqlaunch)
|
||||
ADD_SUBDIRECTORY(dependencies)
|
||||
ADD_SUBDIRECTORY(web_interface)
|
||||
ENDIF(EQEMU_BUILD_SERVER)
|
||||
IF(EQEMU_BUILD_LOGIN)
|
||||
ADD_SUBDIRECTORY(loginserver)
|
||||
|
||||
@@ -1,59 +1,54 @@
|
||||
# EQEmulator Core Server
|
||||
|Travis CI (Linux)|Appveyor (Windows) |
|
||||
|:---:|:---:|
|
||||
|[](https://travis-ci.org/EQEmu/Server) |[](https://ci.appveyor.com/project/KimLS/server/branch/master) |
|
||||
EQEmu
|
||||
===
|
||||
|
||||
***
|
||||
[](https://travis-ci.org/EQEmu/Server)
|
||||
[](https://ci.appveyor.com/project/KimLS/server/branch/master)
|
||||
|
||||
**EQEmulator is a custom completely from-scratch open source server implementation for EverQuest built mostly on C++**
|
||||
* MySQL/MariaDB is used as the database engine (over 200+ tables)
|
||||
* Perl and LUA are both supported scripting languages for NPC/Player/Quest oriented events
|
||||
* Open source database (Project EQ) has content up to expansion GoD (included in server installs)
|
||||
* Game server environments and databases can be heavily customized to create all new experiences
|
||||
* Hundreds of Quests/events created and maintained by Project EQ
|
||||
Overview
|
||||
---
|
||||
|
||||
## Server Installs
|
||||
||Windows|Linux|
|
||||
|:---:|:---:|:---:|
|
||||
|**Install Count**|||
|
||||
### > Windows
|
||||
* [Easy Install](http://wiki.eqemulator.org/p?Akkas_PEQ_Server_Installer&frm=Main#from-scratch-installation-instructions-windows)
|
||||
* [Advanced Setup](http://wiki.eqemulator.org/p?Complete_Windows-based_Server_Setup_Guide)
|
||||
EQEmu is a custom server implementation for EverQuest
|
||||
|
||||
### > Debian/Ubuntu
|
||||
Dependencies
|
||||
---
|
||||
|
||||
> wget --no-check-certificate https://raw.githubusercontent.com/EQEmu/Server/master/utils/scripts/linux_installer/install.sh -O install.sh && chmod 755 install.sh && ./install.sh
|
||||
For Windows: http://eqemu.github.io
|
||||
|
||||
### > CentOS/Fedora
|
||||
Login Server dependencies for Windows/Linux/OSX: http://eqemu.github.io
|
||||
|
||||
> curl -O https://raw.githubusercontent.com/EQEmu/Server/master/utils/scripts/linux_installer/install.sh install.sh && chmod 755 install.sh && ./install.sh
|
||||
For Debian based distros (adjust to your local flavor):
|
||||
|
||||
## Supported Clients
|
||||
- libmysqlclient-dev
|
||||
- libperl-dev
|
||||
- liblua5.1-0-dev (5.2 should work as well)
|
||||
- libboost-dev
|
||||
|
||||
|Titanium Edition|Secrets of Faydwer|Seeds of Destruction|Underfoot|Rain of Fear|
|
||||
|:---:|:---:|:---:|:---:|:---:|
|
||||
|<img src="http://i.imgur.com/hrwDxoM.jpg" height="150">|<img src="http://i.imgur.com/cRDW5tn.png" height="150">|<img src="http://i.imgur.com/V48kuVn.jpg" height="150">|<img src="http://i.imgur.com/IJQ0XMa.jpg" height="150">|<img src="http://i.imgur.com/OMpHkKa.png" height="100">|
|
||||
Further instructions on building the source can be found on the
|
||||
[wiki](http://wiki.eqemulator.org/i?M=Wiki).
|
||||
|
||||
## Bug Reports <img src="http://i.imgur.com/daf1Vjw.png" height="20">
|
||||
* Please use the [issue tracker](https://github.com/EQEmu/Server/issues) provided by GitHub to send us bug
|
||||
Bug reports
|
||||
---
|
||||
|
||||
Please use the [issue tracker](https://github.com/EQEmu/Server/issues) provided by GitHub to send us bug
|
||||
reports or feature requests.
|
||||
* The [EQEmu Forums](http://www.eqemulator.org/forums/) are also a place to submit and get help with bugs.
|
||||
|
||||
## Contributions <img src="http://image.flaticon.com/icons/png/512/25/25231.png" width="20">
|
||||
The [EQEmu Forums](http://www.eqemulator.org/forums/) also have forums to submit
|
||||
bugs/get help with bugs.
|
||||
|
||||
* The preferred way to contribute is to fork the repo and submit a pull request on
|
||||
Contributions
|
||||
---
|
||||
|
||||
The preferred way to contribute is to fork the repo and submit a pull request on
|
||||
GitHub. If you need help with your changes, you can always post on the forums or
|
||||
try Discord. You can also post unified diffs (`git diff` should do the trick) on the
|
||||
try IRC. You can also post unified diffs (`git diff` should do the trick) on the
|
||||
[Server Code Submissions](http://www.eqemulator.org/forums/forumdisplay.php?f=669)
|
||||
forum, although pull requests will be much quicker and easier on all parties.
|
||||
|
||||
## Contact <img src="http://gamerescape.com/wp-content/uploads/2015/06/discord.png" height="20">
|
||||
|
||||
- Discord Channel: https://discord.gg/QHsm7CD
|
||||
- **User Discord Channel**: `#general`
|
||||
- **Developer Discord Channel**: `#eqemucoders`
|
||||
|
||||
Resources
|
||||
Contact
|
||||
---
|
||||
- **User IRC Channel**: `#eqemu` on `irc.eqemulator.net`
|
||||
- **Developer IRC Channel**: `#eqemucoders` on `irc.eqemulator.net`
|
||||
|
||||
- [EQEmulator Forums](http://www.eqemulator.org/forums)
|
||||
- [EQEmulator Wiki](http://wiki.eqemulator.org/i?M=Wiki)
|
||||
|
||||
|
||||
+134
-255
@@ -1,126 +1,5 @@
|
||||
EQEMu Changelog (Started on Sept 24, 2003 15:50)
|
||||
-------------------------------------------------------
|
||||
== 12/03/2016 ==
|
||||
Uleat: Added hack detection to trade code
|
||||
- If illegal items are found in trade slots when the 'trade' button is clicked, the trade is cancelled and a message is sent to the offending player
|
||||
- Future revisions will, at a minimum, log the player as a hacker once the quirks have been worked out
|
||||
|
||||
== 12/01/2016 ==
|
||||
Uleat: Disabled RoF+ clients from augmenting items not in their possessions slots (0-29, 9999, 251-330) to abate an exploit in the current code
|
||||
|
||||
== 10/17/2016 ==
|
||||
Uleat: Moved namespace ItemField from item_instance.h to shareddb.cpp - the only place it is used
|
||||
Uleat: Separated class Inventory from item_instance files into inventory_profile files
|
||||
Uleat: Renamed class Inventory to EQEmu::InventoryProfile
|
||||
Uleat: Renamed enum class InventoryVersion to MobVersion
|
||||
|
||||
== 10/16/2016 ==
|
||||
Uleat: Renamed struct EQEmu::ItemBase to EQEmu::ItemData and class ItemInst to EQEmu::ItemInstance
|
||||
Uleat: Added class EQEmu::InventorySlot. Re-attached pertinent inventory token references to EQDictionary
|
||||
|
||||
== 10/15/2016 ==
|
||||
Uleat: Changed filenames to facilitate future inventory naming conventions
|
||||
|
||||
== 10/09/2016 ==
|
||||
Noudess: Rogue usage of merchants while utilizing sneak was limited to
|
||||
temporary items, as the code that checked faction per item sold did not
|
||||
take into account that rogue was sneaking. Now sneaking rogues can see full
|
||||
inventory on merchants (well, unless an item requires a + faction value).
|
||||
|
||||
== 09/12/2016 ==
|
||||
Akkadius: Massive overhaul of the update system and EQEmu Server management utility framework
|
||||
(known as eqemu_update.pl) now known as eqemu_server.pl
|
||||
- eqemu_server.pl is now a general EQEmu Server management utiltiy framework that can be used
|
||||
to extend to many purposes. It's main purpose is to simplify server management
|
||||
- eqemu_server.pl changes:
|
||||
- Menu has been completely changed, instead of a number based (enter number and hit enter)
|
||||
you now type commands within the menu (Ex: 'database')
|
||||
- Handles last mile installation for Windows Servers (See Github Readme)
|
||||
- Handles last mile installation for Linux Servers (See Github Readme)
|
||||
- Ubuntu
|
||||
- Debian
|
||||
- Fedora
|
||||
- CentOS
|
||||
- Now checks for Internet connection before performing web requests
|
||||
- Database:
|
||||
- Regular schema updates now happen automatically, if new binaries present updated
|
||||
database schema changes, script will backup first, auto update database, and continue
|
||||
world bootup
|
||||
- Regular bots database schema changes now happen automatically similarily to the above
|
||||
- Database checks can also be ran manually via the script menu
|
||||
- CLI Arguments
|
||||
- Arguments passed to eqemu_server.pl can execute the same name-based operations that
|
||||
are present in the interactive menu
|
||||
- Example: "perl eqemu_server.pl opcodes" will download opcodes
|
||||
- Example: "perl eqemu_server.pl backup_player_tables" will backup and export player tables
|
||||
- Bots
|
||||
- Bots can now be automatically setup in Linux or Windows via the 'setup_bots' command
|
||||
- Windows will auto download binaries and install, along with installing bots db schema
|
||||
- Linxu will auto compile binaries and install, along with installings bots db schema
|
||||
- Utility scripts
|
||||
- Linux now has the following utility scripts for download, available via menu 'utility_scripts'
|
||||
and via Linux default install:
|
||||
- server_launcher.pl
|
||||
- server_start_dev.sh
|
||||
- server_start.sh
|
||||
- server_status.sh
|
||||
- server_stop.sh
|
||||
- Usage analytics
|
||||
- eqemu_server.pl now collects usage analytics, this is very helpful for our developers
|
||||
- Example: We can see how many installs have been performed:
|
||||
https://github.com/EQEmu/Server#server-installs
|
||||
- This helps us see how often certain utilities are used as well
|
||||
- Console Messages
|
||||
- All script messages have been prefixed with a bracket action Ex: [Update] [Database] [Info]
|
||||
to be more consistent with our log conventions
|
||||
- 'New Server' Utility
|
||||
- Running 'new_server' from the main menu or 'perl eqemu_server.pl new_server' while in
|
||||
a completely new folder with just the script present, will allow a server operator
|
||||
to initiate a full clean PEQ install in that folder. Pulling down all assets and
|
||||
installing a PEQ database with the name the server operator gives the prompts in the
|
||||
script
|
||||
|
||||
== 09/10/2016 ==
|
||||
noudess: Task system experience based on a % of a level did not take into
|
||||
account the hell levels rule. Now it does.
|
||||
|
||||
== 09/04/2016 (Changes over past few months) ==
|
||||
Akkadius: Fixed an issue where clients would crash with health marquee's
|
||||
Akkadius: Fixed issues with NPC's "ghosting" when they path
|
||||
Akkadius: Overhauled worldserver logging
|
||||
Akkadius: Pets now don't actually spawn until the player has fully entered the zone (Live-like)
|
||||
demonstar/KLS: Adjusted some background workings on how spell buff tics are synced with the client
|
||||
Uleat: Optimizations to map loading and zone times
|
||||
Uleat/Akkadius: Fixed bandolier exploit where you could equip a 2H and Shield
|
||||
mackal: Re-worked spell re-use timer logic
|
||||
mackal: Source optimizations all over, crash fixes
|
||||
mackal: Fixed some issues with illusions on zoning
|
||||
mackal: Fixed some client DOT stacking bugs
|
||||
mackal: Invis will now break on AA spell casts and item cast
|
||||
mackal: Changed how Loot response code works
|
||||
mackal: Implemented 3 additional spell gems with (Mnemonic Retention)
|
||||
mackal: Instant spells now have instrument mods
|
||||
mackal: Rate limit character saves
|
||||
mackal: Made it so items no longer do TGB (Live-like) Rule implemented to disable
|
||||
mackal: Set pet buffs limit to 30
|
||||
|
||||
== 09/03/2016 ==
|
||||
Uleat: Changed 'Bind Wound' behavior to match the best references that I could find for post-2004 era.
|
||||
Note: If you wish to retain the old method, source in the optional '2016_09_03_old_bind_wound_rule.sql' script file.
|
||||
|
||||
== 08/27/2016 ==
|
||||
Kinglykrab: Added optional IP-based account exemptions.
|
||||
- To use this system simply set World:EnableIPExemptions to true and create an entry in the ip_exemptions table.
|
||||
- Example: exemption_ip of IP 192.168.1.4 in ip_exemptions with exemption_amount of 1 will allow only 1 account to login from IP 192.168.1.4.
|
||||
- Note: If there is no exemption, the amount of accounts logged in from a singular IP will default to World:MaxClientsPerIP
|
||||
|
||||
== 08/23/2016 ==
|
||||
noudess: Force mobs on a depop @ end pathgrid to still do this on idle zones.
|
||||
This makes them be more random after a zone is idle, rather than always showing
|
||||
up at start point when 1st person logs into an idle zone. Much more like live.
|
||||
I dion't think this will be much of a performance problem. Once they path and
|
||||
depop, no mkore cpu usage.
|
||||
|
||||
== 08/14/2016 ==
|
||||
mackal: Implement Linked Spell Reuse Timers
|
||||
- For whatever reason this is a bit unfriendly, but that's how it is on live.
|
||||
@@ -516,10 +395,10 @@ mackal: Reworked the activated avoidace skills (riposte, dodge, etc) based on de
|
||||
Also riposte immunity from the increase riposte chance spell effect.
|
||||
|
||||
== 7/2/2015 ==
|
||||
KLS/mackal: AA system has been rewritten fixing a ton of bugs and extending functionality while making it easier to create new AA points.
|
||||
KLS/mackal: New tables are needed and so older data will need to be migrated to the new system.
|
||||
KLS/mackal: The SQL saves the old aa points spent/avail/character_alt_abilities data if any server ops want to do something different than PEQ did with it.
|
||||
KLS/mackal: Will try to get a wiki entry written up next week some time explaining the system but it's really not hard to follow the db tables in the meantime.
|
||||
KLS/Demonstar55: AA system has been rewritten fixing a ton of bugs and extending functionality while making it easier to create new AA points.
|
||||
KLS/Demonstar55: New tables are needed and so older data will need to be migrated to the new system.
|
||||
KLS/Demonstar55: The SQL saves the old aa points spent/avail/character_alt_abilities data if any server ops want to do something different than PEQ did with it.
|
||||
KLS/Demonstar55: Will try to get a wiki entry written up next week some time explaining the system but it's really not hard to follow the db tables in the meantime.
|
||||
|
||||
== 7/1/2015 ==
|
||||
Akkadius: Fix an issue where emote messages would overflow the buffer of 256 by increasing the size and changing some of the initialization
|
||||
@@ -549,7 +428,7 @@ Akkadius: Added DB ver 9082 with update to add npc_types texture columns if tabl
|
||||
Uleat: Added null-term declaration for character names in ENCODE(OP_CharInfo) - where appropriate
|
||||
|
||||
== 05/20/2015 ==
|
||||
mackal: Bard instrument mods should be more consistent with live. Zoning will keep instrument mod for long duration buffs (selo's)
|
||||
demonstar55: Bard instrument mods should be more consistent with live. Zoning will keep instrument mod for long duration buffs (selo's)
|
||||
Still need to have procs/doom effects to inherit the instrument mods from their source buff/whatever
|
||||
|
||||
== 05/18/2015 ==
|
||||
@@ -559,7 +438,7 @@ KLS: Changed how fishing locates water to hopefully be a bit more accurate at th
|
||||
Uleat: Added check to EntityList::CheckSpawnQueue() to bypass dereference if returned iterator is npc_list.end() - should fix the debug assertion failure crash
|
||||
|
||||
== 04/30/2015 ==
|
||||
mackal: Implement mob and client melee push
|
||||
demonstar55: Implement mob and client melee push
|
||||
You can set Combat:MeleePush to false to turn off or change Combat:MeleePushChance to increase the chance an NPC can be pushed
|
||||
PCs are always pushed, need to do more testing to verify.
|
||||
|
||||
@@ -613,7 +492,7 @@ Uleat: Fix for RoF+ clients showing active 'Return Home' button when action is n
|
||||
Noudess: Starting erudites that were supposed to start in paineel were landing in erudin on Titanium. Fixed to be paineel.
|
||||
|
||||
== 02/20/2015 ==
|
||||
mackal: Implement claims for RoF/RoF2 (should no longer crash the client!)
|
||||
demonstar55: Implement claims for RoF/RoF2 (should no longer crash the client!)
|
||||
- fixed bugs related to claims for the rest of the clients (woo infinite loops)
|
||||
|
||||
== 02/18/2015 ==
|
||||
@@ -632,7 +511,7 @@ Notes:
|
||||
|
||||
== 02/16/2015 ==
|
||||
Trevius: (RoF2) Bazaar Trading (Buying/Selling) is now fully functional. Bazaar (/bazaar) search is not yet functional.
|
||||
mackal: (RoF2) Send the bard focus effects, note custom servers will need to fix their items, server side we still use the old system, but RoF2 wasn't showing anything with not sending focus, so send them
|
||||
demonstar55: (RoF2) Send the bard focus effects, note custom servers will need to fix their items, server side we still use the old system, but RoF2 wasn't showing anything with not sending focus, so send them
|
||||
|
||||
== 02/14/2015 ==
|
||||
Trevius: (RoF2) Bazaar is now partially functional. RoF2 clients can start/end trader mode and other clients can purchase from them. No other functionality yet.
|
||||
@@ -682,7 +561,7 @@ Akkadius: Implement Packet logs with dumps
|
||||
See: http://wiki.eqemulator.org/p?Logging_System_Overhaul#packet-logging-levels
|
||||
|
||||
== 02/01/2015 ==
|
||||
mackal: Add quest debugging to lua
|
||||
demonstar55: Add quest debugging to lua
|
||||
eq.debug("Test debug level implicit 1")
|
||||
eq.debug("Test debug level explicit 1", 1)
|
||||
eq.debug("Test debug level explicit 2", 2)
|
||||
@@ -875,7 +754,7 @@ Trevius: Finished lining up the RoF2 Player Profile Struct. Zone times are now
|
||||
Trevius: Fixed zoning after death for RoF2.
|
||||
|
||||
== 12/17/2014 ==
|
||||
mackal: Use vectors for route stuff, should be more CPU cache friendly so faster
|
||||
demonstar55: Use vectors for route stuff, should be more CPU cache friendly so faster
|
||||
Secrets: EQStream changes as recommended by a community member in private.
|
||||
|
||||
== 12/15/2014 ==
|
||||
@@ -885,7 +764,7 @@ Trevius: Player Corpses now saved attuned settings for Items.
|
||||
Required SQL: utils/sql/git/required/2014_12_15_multiple_table_updates.sql
|
||||
|
||||
== 12/13/2014 ==
|
||||
mackal: Fix guild rank spam on zone (needed to be in OP_PP).
|
||||
demonstar55: Fix guild rank spam on zone (needed to be in OP_PP).
|
||||
Trevius: (RoF+) Implemented Armor Ornamentation using Hero's Forge Armor Models. To use, create an ornamentation augment and set the herosforgemodel field in the items table.
|
||||
Trevius: (RoF+) Added command #heromodel (#hm for short) - Usage: #heromodel [hero forge model] [ [slot] ] (example: #heromodel 63)
|
||||
|
||||
@@ -893,11 +772,11 @@ Be sure to run this or there will be item loss:
|
||||
Required SQL: utils/sql/git/required/2014_12_13_inventory_table_update.sql
|
||||
|
||||
== 12/12/2014 ==
|
||||
mackal: Add special attack 42, Ignore Root Aggro Rules. This allows you to root a mob and have them still use the normal aggro rules (so they will attack the one with most hate, not closest)
|
||||
demonstar55: Add special attack 42, Ignore Root Aggro Rules. This allows you to root a mob and have them still use the normal aggro rules (so they will attack the one with most hate, not closest)
|
||||
|
||||
== 12/09/2014 ==
|
||||
Trevius: (RoF+) Implemented Hero's Forge Armor Models for Items. To use, set herosforgemodel field in the item table to a model number such as 63 (for example).
|
||||
mackal: SoF+ swarm pets will no longer be F8able (without a hack!)
|
||||
demonstar55: SoF+ swarm pets will no longer be F8able (without a hack!)
|
||||
|
||||
== 12/08/2014 ==
|
||||
Secrets: Added a feature that allows an EQ client to log in directly to World without having to enter the LoginServer, provided the 'password' field is set in WorldServer.
|
||||
@@ -943,10 +822,10 @@ Trevius: Mercenaries now Dismiss, Suspend, Unsuspend, and Die correctly.
|
||||
Trevius: Mercenaries can now zone once again.
|
||||
|
||||
== 11/17/2014 ==
|
||||
mackal: Correct OP_AugmentInfo reply. This fixes RoF display issue with Adventurer's Stone. Still issues with UF/SoF/SoD though.
|
||||
demonstar55: Correct OP_AugmentInfo reply. This fixes RoF display issue with Adventurer's Stone. Still issues with UF/SoF/SoD though.
|
||||
|
||||
== 11/16/2014 ==
|
||||
mackal: fix size issue with ControlBoat_Struct and exploit fix in OP_BoardBoat
|
||||
demonstar55: fix size issue with ControlBoat_Struct and exploit fix in OP_BoardBoat
|
||||
|
||||
Akkadius: Implemented Automatic Database update and versioning system
|
||||
Akkadius: Created database revision define, this is located in version.h in common #define CURRENT_BINARY_DATABASE_VERSION 9057
|
||||
@@ -1023,12 +902,12 @@ Optional SQL: utils/sql/git/optional/2014_11_15_SwarmPetTargetLock.sql
|
||||
|
||||
== 11/14/2014 ==
|
||||
Secrets: Identified object size and solidtype as flags. Exported them as functions to Perl.
|
||||
mackal: Don't use the hack for charms that doesn't work on RoF
|
||||
mackal: UF too
|
||||
mackal: Tit
|
||||
mackal: SoF
|
||||
mackal: SoD
|
||||
mackal: 62 (untested)
|
||||
demonstar55: Don't use the hack for charms that doesn't work on RoF
|
||||
demonstar55: UF too
|
||||
demonstar55: Tit
|
||||
demonstar55: SoF
|
||||
demonstar55: SoD
|
||||
demonstar55: 62 (untested)
|
||||
|
||||
== 11/13/2014 ==
|
||||
Kayen: Implemented target type (44) 'Beams' (which projects an AE infront of caster with a specified length and width).
|
||||
@@ -1054,7 +933,7 @@ JJ: Implement new Live-like faction adjustment message using rule Client:UseLive
|
||||
Optional SQL: utils/sql/git/optional/2014_11_09_LiveFactionMessages.sql
|
||||
|
||||
== 11/06/2014 ==
|
||||
mackal: Tracking default sort will now be correct order
|
||||
demonstar55: Tracking default sort will now be correct order
|
||||
Trevius: Fixed dynamic merchant list loading. Allows any merchant to be used in any zone.
|
||||
|
||||
== 11/03/2014 ==
|
||||
@@ -1078,17 +957,17 @@ Uleat: Added Client::InterrogateInventory(). Can be invoked by #interrogateinv a
|
||||
Uleat: Fix for stacking items in a world object..added a new command option: #peekinv world - will show world container contents, if one is in use by target.
|
||||
|
||||
== 10/20/2014 ==
|
||||
mackal: Inspect Buffs rank 1 will now show NPC buffs in target window (SoD+)
|
||||
demonstar55: Inspect Buffs rank 1 will now show NPC buffs in target window (SoD+)
|
||||
|
||||
== 10/19/2014 ==
|
||||
Uleat: Updated command #peekinv to display item links properly in RoF clients
|
||||
mackal: Group Mentoring in raids
|
||||
mackal: Inspect Buffs (text only version) works in raid groups
|
||||
mackal: Make use of the Inspect Buffs op/packet. 62 SOL until someone finds its op
|
||||
demonstar55: Group Mentoring in raids
|
||||
demonstar55: Inspect Buffs (text only version) works in raid groups
|
||||
demonstar55: Make use of the Inspect Buffs op/packet. 62 SOL until someone finds its op
|
||||
|
||||
== 10/18/2014==
|
||||
mackal: Implement group mentor, sharing leadership exp (SoF+ only)
|
||||
mackal: Add gaining of group leadership while in raids
|
||||
demonstar55: Implement group mentor, sharing leadership exp (SoF+ only)
|
||||
demonstar55: Add gaining of group leadership while in raids
|
||||
|
||||
== 10/16/2014 ==
|
||||
Uleat: Fixed the auto-conversion view naming error and renamed the views in the script files. Added a fix sql for databases that auto-converted.
|
||||
@@ -1101,7 +980,7 @@ Notes: I modifed the behavior of both load and drop bots to fail on the first op
|
||||
a few altered tables back to their original state - as of the date in the file.
|
||||
|
||||
== 10/13/2014 ==
|
||||
mackal: Partially implement leadership and raids
|
||||
demonstar55: Partially implement leadership and raids
|
||||
Currently working: client side only effects and stat bonuses.
|
||||
Not working: Mark NPC, and other stuff that need extra server side support
|
||||
Currently only UF tested (Tit and 62 may just work, others need packet work)
|
||||
@@ -1110,7 +989,7 @@ mackal: Partially implement leadership and raids
|
||||
Akkadius: Fix for LDON Character Stat load
|
||||
|
||||
== 10/11/2014 ==
|
||||
mackal: Implement Raid MOTD for UF
|
||||
demonstar55: Implement Raid MOTD for UF
|
||||
Don't forget 2014_10_11_RaidMOTD.sql!
|
||||
|
||||
== 10/09/2014 ==
|
||||
@@ -1123,7 +1002,7 @@ previously and/or manually changed code, or just have a need for it to re-run, c
|
||||
** This will only work if you haven't deleted your `character_old` table **
|
||||
|
||||
== 10/07/2014 ==
|
||||
mackal: Identified tutorial flag in all charcreate packets, reworked logic to correctly set homes binds
|
||||
demonstar55: Identified tutorial flag in all charcreate packets, reworked logic to correctly set homes binds
|
||||
|
||||
== 10/05/2014 ==
|
||||
Uleat: Added Server<->Corpse slot translators needed for re-enumeration (inactive until phased in)
|
||||
@@ -1141,13 +1020,13 @@ Uleat: First round of Ti/6.2 translators added - needed for re-enumeration
|
||||
|
||||
== 10/01/2014 ==
|
||||
Kayen: Exported to PERL $client->SendColoredText(color, msg)
|
||||
mackal: Exported SendColoredText to lua
|
||||
demonstar55: Exported SendColoredText to lua
|
||||
|
||||
== 09/30/2014 ==
|
||||
Uleat: Implemented click-casting from bag slots for clients that natively support it (RoF)
|
||||
|
||||
== 09/28/2014 ==
|
||||
mackal: Add support for post June 18, 2014 Hundred Hands Effect spells (they changed the formula and stuff)
|
||||
demonstar55: Add support for post June 18, 2014 Hundred Hands Effect spells (they changed the formula and stuff)
|
||||
set Spells:Jun182014HundredHandsRevamp to true if you're using a spell file from June 18, 2014+
|
||||
|
||||
== 09/27/2014 ==
|
||||
@@ -1156,15 +1035,15 @@ Note: identifier is the stat field in spells_new, slot is used for certain effec
|
||||
Example $mob->GetSpellStat(121, "range"); //Returns spell range
|
||||
Example $mob->GetSpellStat(121, "effectid", 1); //Returns the the value of effectid1
|
||||
This will allow you to pull almost all the data for any spell in quest files.
|
||||
mackal: Move the client's SetAttackTimer to the end of Client::CalcBonuses to keep the haste in sync
|
||||
mackal: Correct haste/slow "stacking" rules
|
||||
mackal: Correct SE_AttackSpeed4 to respect unslowable
|
||||
mackal: Make the haste be between 1-225 like the client (<100 = slow, >100 = haste) to ...
|
||||
mackal: Correct Hundred Hands effect and use formula provided by devs
|
||||
demonstar55: Move the client's SetAttackTimer to the end of Client::CalcBonuses to keep the haste in sync
|
||||
demonstar55: Correct haste/slow "stacking" rules
|
||||
demonstar55: Correct SE_AttackSpeed4 to respect unslowable
|
||||
demonstar55: Make the haste be between 1-225 like the client (<100 = slow, >100 = haste) to ...
|
||||
demonstar55: Correct Hundred Hands effect and use formula provided by devs
|
||||
|
||||
== 09/24/2014 ==
|
||||
Uleat: Re-ordered server opcodes and handlers to give them some predictability of location (I need this for the inventory re-enumeration.)
|
||||
mackal: Added helper function bool EQEmu::IsTradeskill(uint32 skill)
|
||||
demonstar55: Added helper function bool EQEmu::IsTradeskill(uint32 skill)
|
||||
|
||||
== 09/23/2014 ==
|
||||
Kayen: Spell recourse effects will now be applied AFTER the base spells effects have been applied (consistent with live).
|
||||
@@ -1273,46 +1152,46 @@ Akkadius: Player Profile Blob to Database Conversion
|
||||
ORDER BY DATA DESC;
|
||||
|
||||
== 09/20/2014 ==
|
||||
mackal: Fix crash in SendEnterWorld on illegally long names
|
||||
mackal: The client only lets you enter 15 characters for your name (UF at least)
|
||||
mackal: Add rule Spells:SHDProcIDOffByOne for pre-UF spell file, set to true, UF+ set to false
|
||||
demonstar55: Fix crash in SendEnterWorld on illegally long names
|
||||
demonstar55: The client only lets you enter 15 characters for your name (UF at least)
|
||||
demonstar55: Add rule Spells:SHDProcIDOffByOne for pre-UF spell file, set to true, UF+ set to false
|
||||
KLS: #suspend and #ban now have required messages to record the reason for the ban/suspension.
|
||||
|
||||
== 09/19/2014 ==
|
||||
mackal: Added Client::Tell_StringID (used in tell queue messages)
|
||||
mackal: Tell queues (and offline) messages now show correctly
|
||||
mackal: Fix starting with capital check
|
||||
demonstar55: Added Client::Tell_StringID (used in tell queue messages)
|
||||
demonstar55: Tell queues (and offline) messages now show correctly
|
||||
demonstar55: Fix starting with capital check
|
||||
|
||||
== 09/18/2014==
|
||||
mackal: Implement tell queues
|
||||
demonstar55: Implement tell queues
|
||||
Currently set to a limit of 20 by default (World:TellQueueSize) I was unable to hit the limit on live though (100+)
|
||||
The required SQL nukes the old tell queue table, which may or may not be in your DB
|
||||
Optional SQL adds the rule to the DB to allow easy of change
|
||||
Note: this does not play well with multiple sessions with the same name on (crash and relog and have multiple sessions) but normal tells don't play well either
|
||||
|
||||
== 09/16/2014 ==
|
||||
mackal: Implement spell formula 137 (BER AA Desperation)
|
||||
demonstar55: Implement spell formula 137 (BER AA Desperation)
|
||||
Uleat (NateDog): Fix for LoadBuffs() crash when a spell with a non-persistent Illusion effect was loaded.
|
||||
mackal: Fix some effect calcs + implement more (derived from the client)
|
||||
demonstar55: Fix some effect calcs + implement more (derived from the client)
|
||||
|
||||
== 09/15/2014 ==
|
||||
Kayen: Nimbus effects will now be reapplied after zoning and will be removed when associated buff fades.
|
||||
|
||||
== 09/13/2014 ==
|
||||
mackal: Fix rogues not having Thieves' Cant
|
||||
demonstar55: Fix rogues not having Thieves' Cant
|
||||
|
||||
== 09/09/2014 ==
|
||||
mackal: Incrase Mob kick/bash timer by 3
|
||||
demonstar55: Incrase Mob kick/bash timer by 3
|
||||
see: http://www.eqemulator.org/forums/showthread.php?t=38734
|
||||
mackal: Fix slow effect on NPC special attack reuse timers
|
||||
demonstar55: Fix slow effect on NPC special attack reuse timers
|
||||
see: http://www.eqemulator.org/forums/showthread.php?t=38734
|
||||
mackal: Slow fixes to bots!
|
||||
mackal: Revamped how NPC attack rate is set
|
||||
demonstar55: Slow fixes to bots!
|
||||
demonstar55: Revamped how NPC attack rate is set
|
||||
SQL: 2014_09_09_attack_delay.sql
|
||||
mackal: Added attackdelay to #npcedit
|
||||
demonstar55: Added attackdelay to #npcedit
|
||||
|
||||
== 09/08/2014 ==
|
||||
mackal: Fix slow calc
|
||||
demonstar55: Fix slow calc
|
||||
see: http://www.eqemulator.org/forums/showthread.php?t=38734
|
||||
|
||||
== 09/07/2014 ==
|
||||
@@ -1323,18 +1202,18 @@ Uleat: Tweaked 'Smart' trading code to return main slots before sub slots in sta
|
||||
|
||||
== 09/05/2014 ==
|
||||
Uleat: Fix for cursor item loss when zoning. (Thanks to the other devs who traced and fixed the 'macro' issue!)
|
||||
mackal: Fix size getting nuked with lua's SendIllusionPacket
|
||||
demonstar55: Fix size getting nuked with lua's SendIllusionPacket
|
||||
|
||||
== 09/03/2014 ==
|
||||
Secrets: Identified the routines needed to augment items in RoF. Currently, only Insert and Remove are supported. Swap and Destroy do not work due to missing functions related to the cursor.
|
||||
mackal: Added work around command to show numhits on your buffs (#shownumhits)
|
||||
demonstar55: Added work around command to show numhits on your buffs (#shownumhits)
|
||||
Uleat: Fix for timer issue introduced by Zone::ShutDown() fix.
|
||||
|
||||
== 09/02/2014 ==
|
||||
Secrets: Identified OP_GuildPromote for RoF clients.
|
||||
Secrets: Fixed promotion, demotion, transferring a leader and displaying of client ranks in the Rain of Fear client. The rain of fear client, as such, will only have 3 ranks like the other clients, but supports a theoretical 8 ranks later.
|
||||
Secrets/Akkadius: Fixed an issue involving character name lookup in the new DB code.
|
||||
mackal: crash fix checking DivineAura in hate_list.cpp
|
||||
demonstar55: crash fix checking DivineAura in hate_list.cpp
|
||||
Secrets: Reverted some code that got in the main branch that shouldn't have gotten there.
|
||||
Uleat: Changed #loc to report the same precision as /loc for Cartesians
|
||||
|
||||
@@ -1345,7 +1224,7 @@ KLS: Fixed a few quest related inconsistencies.
|
||||
KLS: Added Lua EntityList::ChannelMessage(from, type, msg, language)
|
||||
|
||||
== 08/30/2014 ==
|
||||
mackal: (noudess) Merchants should be more descriptive of why they don't sell to you
|
||||
demonstar55: (noudess) Merchants should be more descriptive of why they don't sell to you
|
||||
|
||||
== 08/26/2014 ==
|
||||
Uleat: Implemented 'Smart' Player Trade transfers. Trades are processed by containers, stackables and then all remaining. QueryServ logs have been updated to match these transactions.
|
||||
@@ -1723,7 +1602,7 @@ Optional SQL: utils/sql/git/optional/2014_04_03_SpellProjectileRules.sql
|
||||
Note: The rules in this SQL are for setting the item id for the graphic used by the projectile on different clients.
|
||||
|
||||
== 04/01/2014 ==
|
||||
mackal: Implemented ability for a merchant to open and close shop.
|
||||
demonstar55: Implemented ability for a merchant to open and close shop.
|
||||
Lua quest functions: e.self:MerchantOpenShop() and e.self:MerchantCloseShop()
|
||||
GM Commands: #merchant_open_shop (short: #open_shop) and #merchant_close_shop (short: #close_shop)
|
||||
default to status 100, just in case you need to force the merchants status
|
||||
@@ -1789,7 +1668,7 @@ Kayen: Revision to lull/harmony/pacification code to be consistent with live bas
|
||||
which if 'resisted' will cause the caster to gain aggro.
|
||||
|
||||
== 03/05/2014 ==
|
||||
mackal: Corrected rogue's evade to be single target
|
||||
demonstar55: Corrected rogue's evade to be single target
|
||||
sorvani: fixed crash issue 119
|
||||
|
||||
== 03/04/2014 ==
|
||||
@@ -1804,7 +1683,7 @@ Kayen: Revision to root code to be consistent with live based on extensive perso
|
||||
Optional SQL: utils/sql/git/optional/2014_03_04_RootRule.sql
|
||||
|
||||
== 03/03/2014 ==
|
||||
mackal: Implemented deadly strikes and gave rogues higher innate throwing crit chance
|
||||
demonstar55: Implemented deadly strikes and gave rogues higher innate throwing crit chance
|
||||
|
||||
New rules: Combat:RogueCritThrowingChance, Combat:RogueDeadlyStrikeChance, Combat:RogueDeadlyStrikeMod
|
||||
Defaults should give fairly close to live results
|
||||
@@ -1816,7 +1695,7 @@ Kayen: Revision to charm code to be consistent with live based on extensive pers
|
||||
|
||||
Optional SQL: utils/sql/git/optional/2014_03_02_CharmRules.sql
|
||||
|
||||
mackal: Melee Crits, HoTs, DoTs messages should now be filtered correctly on all clients.
|
||||
demonstar55: Melee Crits, HoTs, DoTs messages should now be filtered correctly on all clients.
|
||||
Clients that also support seeing others DoTs will now see them if they don't filter them
|
||||
note: some newer clients have a 'mine only' option for HoTs but it functions the same as show
|
||||
|
||||
@@ -1868,7 +1747,7 @@ Sorvani: Renamed the instance_lockout and instance_lockout_player tables to inst
|
||||
Required SQL: utils/sql/git/2014_02_13_Rename_instance_lockout_tables.sql
|
||||
|
||||
== 02/10/2014 ==
|
||||
mackal (Secrets): Re-wrote the entity list to be a std::map. This should be used for direct entityID lookups and is noticably faster performance-wise. Also should result in less nil pointers potentially.
|
||||
demonstar55 (Secrets): Re-wrote the entity list to be a std::map. This should be used for direct entityID lookups and is noticably faster performance-wise. Also should result in less nil pointers potentially.
|
||||
Secrets: Fixed a crash issue that could occur on #repop related to quest timers.
|
||||
Kayen: Divine Arbiration and other similar spell effects will now utilize a spell range check.
|
||||
Kayen: Revised how heal amount is calculated to properly incorporate all current focus effects/bonuses.
|
||||
@@ -1899,14 +1778,14 @@ Kayen: Implemented SE_FfLimitUseType (focus limit to numhits type)
|
||||
|
||||
== 01/20/2014 ==
|
||||
cavedude: Live-Like weather system (Thanks to robregen for figuring it out!)
|
||||
mackal: Implemented not_extendable spell flag
|
||||
mackal: Moved Spell Casting Reinforcement to DB
|
||||
mackal: Moved Mez Mastery to DB
|
||||
demonstar55: Implemented not_extendable spell flag
|
||||
demonstar55: Moved Spell Casting Reinforcement to DB
|
||||
demonstar55: Moved Mez Mastery to DB
|
||||
Kayen: Complete revision of the numhits systems to utilize 'numhits type' field in spell file.
|
||||
|
||||
== 01/18/2014 ==
|
||||
sorvani: Implemented for Lua eq.get_characters_in_instance(uint16 instance_id), return a Lua HashTable
|
||||
mackal: NPCs will now cast their charms.
|
||||
demonstar55: NPCs will now cast their charms.
|
||||
|
||||
== 01/13/2014 ==
|
||||
Kayen: Numerous minor fixes to spell effects.
|
||||
@@ -1926,19 +1805,19 @@ Kayen: Implemented SE_LimitRace (Limits to spells cast by a certain race)
|
||||
Kayen: Implemented SE_FcMute (silences casting of spells that contain specific spell effects) ie silence only heals
|
||||
|
||||
== 01/09/2014 ==
|
||||
mackal: Add pet size preservation like live (zone, camp, etc)
|
||||
demonstar55: Add pet size preservation like live (zone, camp, etc)
|
||||
|
||||
== 01/07/2014 ==
|
||||
mackal: Moved pet can attack check to before it tries to attack, which is more live like.
|
||||
demonstar55: Moved pet can attack check to before it tries to attack, which is more live like.
|
||||
|
||||
== 01/03/2014 ==
|
||||
mackal: Crash prevention for emote.
|
||||
demonstar55: Crash prevention for emote.
|
||||
|
||||
== 01/02/2014 ==
|
||||
mackal: Stuns from beneficial spells (Harvest) ignore immunity
|
||||
demonstar55: Stuns from beneficial spells (Harvest) ignore immunity
|
||||
|
||||
== 12/26/2013 ==
|
||||
mackal: Added classes_required to merchantlist (same bitmask as items)
|
||||
demonstar55: Added classes_required to merchantlist (same bitmask as items)
|
||||
|
||||
== 12/24/2013 ==
|
||||
Secrets (Akkadius): Perl $client->SilentMessage("Message"); addition, this is a pre-req for a Perl plugin I've shared with EQEmu. This function essentially mimics a player speaking with an NPC - which is used in popup window responses
|
||||
@@ -1959,14 +1838,14 @@ Kayen: Implemented SE_TriggerOnAmountValue (Trigger spell if HP/Mana/End bellow
|
||||
Kayen: Fix to SE_BlockNextSpellFocus to make it functional again.
|
||||
|
||||
== 12/15/2013 ==
|
||||
mackal: Moved the blocked buff check down so we get spell effects like on live
|
||||
demonstar55: Moved the blocked buff check down so we get spell effects like on live
|
||||
Kayen: Implemented SE_ReduceHealing (Reduces amount of healing on target by X amount)
|
||||
Kayen: Implemented SE_CastonFocusEffect (Triggers spell as part of a focus, when that focus effect is used)
|
||||
Kayen: Implemented SE_IncreaseHitDmgTaken (Effect is triggered when X amount of damage is taken)
|
||||
Kayen: More fixes for various spell triggers/procs to now properly use their resist modifier.
|
||||
|
||||
== 12/14/2013 ==
|
||||
mackal: Blocked buffs shouldn't fail, they should just not be applied.
|
||||
demonstar55: Blocked buffs shouldn't fail, they should just not be applied.
|
||||
JJ: Changed enable/disable recipe to confirm change made.
|
||||
|
||||
== 12/13/2013 ==
|
||||
@@ -1977,52 +1856,52 @@ Kayen: Fix for various spell triggers/procs to now properly use their resist mod
|
||||
Kayen: Fix to mob->ModSkillDmgTaken(skill_num, value), setting value to -1 will now properly effect all skills.
|
||||
|
||||
== 12/11/2013 ==
|
||||
mackal: Fixed issue with crippling blow from berserker frenzy not actually doing anything
|
||||
mackal: Fix haste caps
|
||||
demonstar55: Fixed issue with crippling blow from berserker frenzy not actually doing anything
|
||||
demonstar55: Fix haste caps
|
||||
|
||||
== 12/04/2013 ==
|
||||
mackal: Fixed SpellType_Charm case in AICastSpell
|
||||
demonstar55: Fixed SpellType_Charm case in AICastSpell
|
||||
|
||||
== 12/03/2013 ==
|
||||
mackal: Added #showspellslist to view a mobs spell list
|
||||
mackal: Fix procing off of unattackable things
|
||||
demonstar55: Added #showspellslist to view a mobs spell list
|
||||
demonstar55: Fix procing off of unattackable things
|
||||
|
||||
== 12/02/2013 ==
|
||||
JJ: Bandaid fix to CopyCharacter function.
|
||||
|
||||
== 11/29/2013 ==
|
||||
mackal: Stacking issues should be resolved now, probably could be optimized more, but went from 3 loops that do stuff to 3 where only 2 really does stuff and one breaks early in most cases, so slightly better
|
||||
demonstar55: Stacking issues should be resolved now, probably could be optimized more, but went from 3 loops that do stuff to 3 where only 2 really does stuff and one breaks early in most cases, so slightly better
|
||||
|
||||
== 11/23/2013 ==
|
||||
Secrets: Fixed an issue related to a zone crash where the count of the abilities in an AA was 0, leading to a size 0 buffer issue.
|
||||
|
||||
== 11/19/2013 ==
|
||||
Secrets: Fixed an issue with two zone crashes reported on PEQ related to the buff restrictions code and AAs.
|
||||
mackal: Partially make use of dot_stacking_exempt (case when it's 1 is implemented, -1 case isn't)
|
||||
demonstar55: Partially make use of dot_stacking_exempt (case when it's 1 is implemented, -1 case isn't)
|
||||
|
||||
== 11/18/2013 ==
|
||||
mackal: Added assistradius to npc_types, defaults to aggroradius if set to 0 (old behaviour)
|
||||
demonstar55: Added assistradius to npc_types, defaults to aggroradius if set to 0 (old behaviour)
|
||||
|
||||
== 11/17/2013 ==
|
||||
Sorvani: fixed leash and tether special abilities to use the specified range correctly.
|
||||
mackal: Rewrote the Mob::_GetMovementSpeed fix an issue that arose from the change on 11/11
|
||||
demonstar55: Rewrote the Mob::_GetMovementSpeed fix an issue that arose from the change on 11/11
|
||||
- Added the rule Character:BaseRunSpeedCap (default 158) so people can customize what their runspeed cap is. Hardcapped to 225 so stuff doesn't get too crazy.
|
||||
|
||||
== 11/16/2013 ==
|
||||
Leere: Fixed the drinking message for auto-consume, it will again correctly show up for forced consumption instead.
|
||||
mackal: Added Mob::DoCastingChecks() which will check for various fail conditions while the casting bar is up. This is called after Mob::DoCastSpell() starts the casting and before it returns.
|
||||
demonstar55: Added Mob::DoCastingChecks() which will check for various fail conditions while the casting bar is up. This is called after Mob::DoCastSpell() starts the casting and before it returns.
|
||||
|
||||
== 11/15/2013 ==
|
||||
mackal: Fixed Mob::CalcFocusEffect()'s SE_LimitEffect
|
||||
demonstar55: Fixed Mob::CalcFocusEffect()'s SE_LimitEffect
|
||||
Leere: Fixed a stacking issue for SE_StackingCommand_Block
|
||||
|
||||
== 11/13/2013 ==
|
||||
mackal: Implemented bard song effect cap. You can set the base cap with the rule Character:BaseInstrumentSoftCap, defaults to 36 or "3.6" as it is sometimes referred to.
|
||||
mackal: Fix Echo of Taelosia and Ayonae's Tutelage to increase the mod cap instead of further improving the instrument mod
|
||||
mackal: Implemented Singing/Instrument Mastery as an AA bonus.
|
||||
demonstar55: Implemented bard song effect cap. You can set the base cap with the rule Character:BaseInstrumentSoftCap, defaults to 36 or "3.6" as it is sometimes referred to.
|
||||
demonstar55: Fix Echo of Taelosia and Ayonae's Tutelage to increase the mod cap instead of further improving the instrument mod
|
||||
demonstar55: Implemented Singing/Instrument Mastery as an AA bonus.
|
||||
|
||||
== 11/11/2013 ==
|
||||
mackal: Changed the way walk speed is calculated to allow mobs to have their walk speed equal a 100% movement reduction
|
||||
demonstar55: Changed the way walk speed is calculated to allow mobs to have their walk speed equal a 100% movement reduction
|
||||
|
||||
== 11/09/2013 ==
|
||||
Leere: Fixed Bard mana regen, they now only are affected by items and AA.
|
||||
@@ -2072,50 +1951,50 @@ Uleat: Converted SkillType typedef enumeration to SkillUseTypes enumeration - So
|
||||
Uleat: Prepped the client patch files for larger skill buffer size (not active)
|
||||
|
||||
== 10/24/2013 ==
|
||||
mackal: Fix some memory leaks in Mob::SpellOnTarget
|
||||
demonstar55: Fix some memory leaks in Mob::SpellOnTarget
|
||||
|
||||
== 10/21/2013 ==
|
||||
mackal: Changed GetMinLevel return 0 for more cases that EQ uses for some reason ...
|
||||
mackal: Added buff level restrictions, set the Spells:BuffLevelRestrictions to false to have the old behavior.
|
||||
demonstar55: Changed GetMinLevel return 0 for more cases that EQ uses for some reason ...
|
||||
demonstar55: Added buff level restrictions, set the Spells:BuffLevelRestrictions to false to have the old behavior.
|
||||
|
||||
== 10/18/2013 ==
|
||||
Uleat: Expanded the 'Bag Type' enumeration to include all known values. Also, set in place additional 'Bag Type' to 'Skill Type' conversions. Some of these will need to be verified before activation.
|
||||
Uleat: Cleaned up some unused enumerations to show a move towards standardization. More to come...
|
||||
|
||||
== 10/12/2013 ==
|
||||
mackal: Allow Titanium and lower clients to enter Tutorial zone from character select
|
||||
demonstar55: Allow Titanium and lower clients to enter Tutorial zone from character select
|
||||
Bad_Captain: Fixed merc crash issue by updating special_abilities & vwMercNpcTypes (Sorvani).
|
||||
Bad_Captain: Bots- added out of combat bard songs & #bot bardoutofcombat on|off command to turn them on/off.
|
||||
|
||||
== 10/11/2013 ==
|
||||
JJ: (mackal) Allow use of Go Home button when Tutorial still selected in RoF.
|
||||
JJ: (demonstar55) Allow use of Go Home button when Tutorial still selected in RoF.
|
||||
|
||||
== 10/10/2013 ==
|
||||
Secrets: Fixed zone shutdown (or #reloadqst) reinitalization of Perl. This should allow for Perl 5.14 and later to work on Windows under the new quest system.
|
||||
mackal: Beneficial single target buffs shouldn't have their mana/timers set if they fail to cast after the Mob::SpellOnTarget call in Mob::SpellFinished
|
||||
demonstar55: Beneficial single target buffs shouldn't have their mana/timers set if they fail to cast after the Mob::SpellOnTarget call in Mob::SpellFinished
|
||||
JJ: Revert change to EnterWorldPacket introduced on 22 April 2013 to fix inability to enter Tutorial or Go Home from character select screen.
|
||||
|
||||
== 10/09/2013 ==
|
||||
mackal: Fixed some more instances of the AA timer being eaten
|
||||
demonstar55: Fixed some more instances of the AA timer being eaten
|
||||
|
||||
== 10/08/2013 ==
|
||||
mackal: Added IsBuffSpell(spell_id) that will return true if the spell has a duration, so would end up in effects/song/discs etc windows on the client
|
||||
mackal: Replaced instances of using CalcBuffDuration to determine if a spell was a buff with IsBuffSpell
|
||||
mackal: Removed Mob::HasBuffIcon since it was doing what IsBuffSpell does in a more convoluted way with a rather misleading name
|
||||
mackal: Fixed issues that arose from the 10/03/2013 change
|
||||
demonstar55: Added IsBuffSpell(spell_id) that will return true if the spell has a duration, so would end up in effects/song/discs etc windows on the client
|
||||
demonstar55: Replaced instances of using CalcBuffDuration to determine if a spell was a buff with IsBuffSpell
|
||||
demonstar55: Removed Mob::HasBuffIcon since it was doing what IsBuffSpell does in a more convoluted way with a rather misleading name
|
||||
demonstar55: Fixed issues that arose from the 10/03/2013 change
|
||||
|
||||
== 10/05/2013 ==
|
||||
Sorvani: fixed issue with stackable items being created with 0 charges cause by fix to SummonItems
|
||||
|
||||
== 10/03/2013 ==
|
||||
mackal: Fix when the random +1 tick is added to nerf extension focus effects to where they should be
|
||||
demonstar55: Fix when the random +1 tick is added to nerf extension focus effects to where they should be
|
||||
|
||||
== 09/30/2013 ==
|
||||
Sorvani: Changed SummonItem to only summon an item with max charges when said default value is present and not on zero charges
|
||||
mackal: Fixed issue with #showstats showing your level for a bunch of values
|
||||
demonstar55: Fixed issue with #showstats showing your level for a bunch of values
|
||||
|
||||
== 09/13/2013 ==
|
||||
mackal: Add support for /pet hold on and /pet hold off (UF and RoF)
|
||||
demonstar55: Add support for /pet hold on and /pet hold off (UF and RoF)
|
||||
|
||||
== 08/29/2013 ==
|
||||
KLS: Removed Common Profiler and Zone Profiler. They're well past outdated status and are just code bloat.
|
||||
@@ -2261,8 +2140,8 @@ KLS: Perl now will (like lua) keep track of the values you return from EVENT_*.
|
||||
KLS: Exported eq.follow(entity_id, [distance]) and eq.stop_follow() to lua.
|
||||
|
||||
== 07/01/2013 ==
|
||||
mackal: Fix Monster Summoning related to giants/cyclops
|
||||
mackal: Prevent Monster Summoning from summoning a portal in bothunder
|
||||
demonstar55: Fix Monster Summoning related to giants/cyclops
|
||||
demonstar55: Prevent Monster Summoning from summoning a portal in bothunder
|
||||
KLS: Merge of lua branch to master
|
||||
See: http://www.eqemulator.org/forums/showthread.php?t=37008 for more detailed information on what is added.
|
||||
Upgrade notes:
|
||||
@@ -2330,35 +2209,35 @@ JJ: Fixed rare case where heals from buffs could go negative.
|
||||
Derision: Moved entity_list.Clear() prior to destruction of Perl objects in zone shutdown as I was seeing a segfault due to attempts to call EVENT_HATE_LIST as mobs were being destroyed.
|
||||
|
||||
== 04/09/2013 ==
|
||||
mackal: Realized I was an idiot, changed salvage script to be better
|
||||
demonstar55: Realized I was an idiot, changed salvage script to be better
|
||||
optional SQL: 2013_04_09_SalvageCleanOld.sql - run if ran old script
|
||||
|
||||
== 04/08/2013 ==
|
||||
mackal: Implemented Salvage AA
|
||||
demonstar55: Implemented Salvage AA
|
||||
required SQL: 2013_04_08_Salvage.sql
|
||||
script: generate_salvage.py - will generate the entries for some exceptions for salvage returns.
|
||||
|
||||
== 04/04/2013 ==
|
||||
mackal: Implemented SE_ForageAdditionalItems as a bonus
|
||||
demonstar55: Implemented SE_ForageAdditionalItems as a bonus
|
||||
required SQL: 2013_04_04_NaturesBounty.sql
|
||||
|
||||
== 04/03/2013 ==
|
||||
mackal: Overloaded Mob::Say_StringID with the option to provide a message type
|
||||
mackal: Switched rest of the Pet Messages to MT_PetResponse (Leader commands intentionally left the old way)
|
||||
demonstar55: Overloaded Mob::Say_StringID with the option to provide a message type
|
||||
demonstar55: Switched rest of the Pet Messages to MT_PetResponse (Leader commands intentionally left the old way)
|
||||
|
||||
== 04/2/2013 ==
|
||||
Bad_Captain: Fixed Merc lack of use of heal over time spells (causing excessive healing).
|
||||
Bad_Captain: Fixed pet mitigation/AC issues.
|
||||
|
||||
== 04/01/2013 ==
|
||||
mackal: AA reuse timers now start when you hit the button and are reset upon failure
|
||||
mackal: Instant Cast bard AAs can now be used while singing a song
|
||||
demonstar55: AA reuse timers now start when you hit the button and are reset upon failure
|
||||
demonstar55: Instant Cast bard AAs can now be used while singing a song
|
||||
|
||||
== 03/30/2013 ==
|
||||
mackal: Fixed most of the pet talking, all use StringIDs now. Pet now informs you when it taunts.
|
||||
demonstar55: Fixed most of the pet talking, all use StringIDs now. Pet now informs you when it taunts.
|
||||
|
||||
== 03/23/2013 ==
|
||||
mackal: Fix issues with escape not always working and fixed SE_FadingMemories to have the message since the message isn't part of the spell data.
|
||||
demonstar55: Fix issues with escape not always working and fixed SE_FadingMemories to have the message since the message isn't part of the spell data.
|
||||
Escape now uses just the spell and not the AA Actoin
|
||||
Fading Memories now only uses the AA Action to eat mana
|
||||
|
||||
@@ -2368,7 +2247,7 @@ Bad_Captain: Added checks before dismissing merc to prevent possible bugged merc
|
||||
Bad_Captain: Merged in Secret's merc memory leak fixes.
|
||||
|
||||
== 03/20/2013 ==
|
||||
mackal: Fixed stacking issues with SE_Limit* (ex. Unholy Aura Discipline and Aura of Reverence)
|
||||
demonstar55: Fixed stacking issues with SE_Limit* (ex. Unholy Aura Discipline and Aura of Reverence)
|
||||
|
||||
== 03/18/2013 ==
|
||||
Bad_Captain: Fixed zone crash due to merc focus effects & tribute.
|
||||
@@ -2431,7 +2310,7 @@ KLS: Changed how shared memory works:
|
||||
af4t: Add Touch of the Wicked AA redux to SK Improved Harm Touch and Leech Touch.
|
||||
|
||||
== 02/22/2013 ==
|
||||
mackal: Mobs will now be removed from XTargets when they get back to their way point, should be last instance of XTarget mobs not clearing when they are not aggroed anymore
|
||||
demonstar55: Mobs will now be removed from XTargets when they get back to their way point, should be last instance of XTarget mobs not clearing when they are not aggroed anymore
|
||||
|
||||
== 02/19/2013 ==
|
||||
Derision: World should no longer crash if the start_zone query fails at character creation.
|
||||
@@ -2440,7 +2319,7 @@ Derision: World should no longer crash if the start_zone query fails at characte
|
||||
Bad_Captain: Moved merc save to merc table, save merc buffs, added cure and rez spells to healer merc.
|
||||
JJ: Chat garbled for drunk characters.
|
||||
Derision: Charmed pets should no longer be targettable with F8. Charmed pets no longer get a surname of Soandso's Pet.
|
||||
mackal: Added potionbelt tool tip
|
||||
demonstar55: Added potionbelt tool tip
|
||||
KLS: Added EVENT_DEATH to Player Quests
|
||||
|
||||
REQUIRED SQL: 2013_02_18_Merc_Rules_and_Tables.sql
|
||||
@@ -2452,8 +2331,8 @@ Derision: Client version is now returned by the stream proxy as a number.
|
||||
Derision: Fixed bug where BecomeTrader packets were only being sent to the Trader, not all other clients in the bazaar.
|
||||
|
||||
== 02/16/2013 ==
|
||||
mackal: Fix AA reuse timer calc
|
||||
mackal: Remove old filters and change all remaining old to new (Also fix Auction filtering out OOC as well due to incorrect define)
|
||||
demonstar55: Fix AA reuse timer calc
|
||||
demonstar55: Remove old filters and change all remaining old to new (Also fix Auction filtering out OOC as well due to incorrect define)
|
||||
|
||||
== 02/12/2013 ==
|
||||
Kayen: AA fix
|
||||
@@ -2464,7 +2343,7 @@ REQUIRED SQL: utils/sql/svn/2504_required_aa_updates.sql
|
||||
Derision: RoF: Added ENCODE for OP_BeginCast (fixes no sound during spell casting). Corrected OP_DeleteSpell.
|
||||
|
||||
== 02/10/2013 ==
|
||||
JJ: (mackal) Language skill up should use proper function.
|
||||
JJ: (demonstar55) Language skill up should use proper function.
|
||||
JJ: SetLanguageSkill now updates client immediately. Both functions do proper limit checks.
|
||||
Added two missing languages. Skill level 0 in a spoken language now shows 'in an unknown tongue'.
|
||||
JJ: Initial implementation of a GarbleMessage function and implemented for languages. Can be shared with drunk speaking.
|
||||
@@ -2500,7 +2379,7 @@ Trevius: RoF: Turning on Trader mode in bazaar now works, but no further trader
|
||||
Akkadius: Fixed an issue where global_npc.pl was not initializing (initially)
|
||||
|
||||
== 01/31/2013 ==
|
||||
cavedude00: (mackal) Rune aggro fix
|
||||
cavedude00: (demonstar55) Rune aggro fix
|
||||
cavedude00: (Drajor) Tradeskill skillneeded fix.
|
||||
|
||||
== 01/30/2013 ==
|
||||
@@ -2534,7 +2413,7 @@ Bad_Captain: Mercs - Initial spell casting AI committed.
|
||||
KLS: Added crash logging for Windows builds.
|
||||
Trevius: Mercenaries now despawn when a player camps out or disconnects in any way.
|
||||
Trevius: Players with a Mercenary spawned can now be invited to and join another group with their mercenary.
|
||||
Sorvani: (mackal): Moved stunproc rule implmentation to catch all cases
|
||||
Sorvani: (Demonstar55): Moved stunproc rule implmentation to catch all cases
|
||||
|
||||
OPTIONAL SQL: utils/sql/svn/mercs.sql -- rerun for updated merc stats & merc spell lists
|
||||
|
||||
@@ -2985,9 +2864,9 @@ references:
|
||||
http://www.eqemulator.org/forums/showthread.php?t=35629 - CSD Bugged Corpse Patch
|
||||
http://www.eqemulator.org/forums/showthread.php?t=35699 - CSD Bandolier Patch
|
||||
|
||||
cavedude: (mackal) Damage shields by default will no longer count towards EXP gain. (Rule also added to change this behaviour.)
|
||||
cavedude: (mackal) Extended targets should now clear when aggro is lost using skills.
|
||||
cavedude: (mackal) AAs with shorter reuse timers should now reset if the cast failed (interrupted.)
|
||||
cavedude: (demonstar55) Damage shields by default will no longer count towards EXP gain. (Rule also added to change this behaviour.)
|
||||
cavedude: (demonstar55) Extended targets should now clear when aggro is lost using skills.
|
||||
cavedude: (demonstar55) AAs with shorter reuse timers should now reset if the cast failed (interrupted.)
|
||||
KLS: Fixed a cause of raids disbanding on zoning.
|
||||
|
||||
OPTIONAL SQL: INSERT INTO `rule_values` VALUES (1, 'Combat:EXPFromDmgShield', 'false', 'Determine if damage from a damage shield counts for EXP gain.');
|
||||
@@ -3364,7 +3243,7 @@ Kayen: Implemented Perl Mob Quest Object GetModVulnerability(resist type) - Retu
|
||||
Optional SQL: utils/sql/svn/2154_optional_rule_spell_procs_resists_falloff.sql
|
||||
|
||||
==06/22/2012==
|
||||
Secrets: (mackal) Spells now display to all clients and can be filtered as such.
|
||||
Secrets: (demonstar55) Spells now display to all clients and can be filtered as such.
|
||||
Secrets: Damage Shields now go to the proper filter, and do not show the non-melee damage to everyone.
|
||||
|
||||
==06/03/2012==
|
||||
@@ -5519,10 +5398,10 @@ WildcardX: *BOTS* Bots can now be invited and disbanded from your group by simpl
|
||||
WildcardX: *BOTS* Tweak to the bots total play time calculation to make it more accurate.
|
||||
KLS: Added #path meshtest simple to do a faster search on errant path nodes.
|
||||
KLS: Modified the accurate hazard code to make automatic path maps with more accurate info that requires less manual editing afterward.
|
||||
cavedude: (mackal) Pets will now be amiable to their owners, indifferent to all else.
|
||||
cavedude: (mackal) Added $client->KeyRingCheck() and $client->KeyRingAdd() to allow Perl to manipulate the keyring.
|
||||
cavedude: (mackal) Casting an invis spell on a player that already has a similar type invis spell will no longer drop the existing buff.
|
||||
cavedude: (mackal) Corrected message string for heal spells.
|
||||
cavedude: (demonstar55) Pets will now be amiable to their owners, indifferent to all else.
|
||||
cavedude: (demonstar55) Added $client->KeyRingCheck() and $client->KeyRingAdd() to allow Perl to manipulate the keyring.
|
||||
cavedude: (demonstar55) Casting an invis spell on a player that already has a similar type invis spell will no longer drop the existing buff.
|
||||
cavedude: (demonstar55) Corrected message string for heal spells.
|
||||
cavedude: Added rule to determine at what HP a fleeing NPC will halt due to being snared.
|
||||
|
||||
==08/07/2009==
|
||||
@@ -6158,7 +6037,7 @@ KLS: Fixed the /bug structure and updated the table to be more useful.
|
||||
Required SQL: .\utils\sql\svn\503_bugs.sql
|
||||
|
||||
==05/11/2009==
|
||||
mackal: Added a function to allow Perl to check augments within items.
|
||||
demonstar55: Added a function to allow Perl to check augments within items.
|
||||
cavedude: Increased bind wound skill up speed some.
|
||||
KLS: Fix for potentially dangerous typo in spawn conditions code.
|
||||
KLS: Removed some non-functioning but still taking up database resources database code.
|
||||
@@ -6459,7 +6338,7 @@ cavedude: Removed the USE_RACE_CLASS_XP_MODS define as it was outdated and horri
|
||||
cavedude: Added group XP bonus. The larger the group, the higher the XP gain.
|
||||
cavedude: Added XP bonus for Warrior, Rogue, and Halfling.
|
||||
cavedude: Corrected ZEM for AAs.
|
||||
cavedude: (Thanks to mackal) Pet Affinity will no longer effect charmed pets.
|
||||
cavedude: (Thanks to demonstar55) Pet Affinity will no longer effect charmed pets.
|
||||
cavedude: (realityincarnate) Bard songs that require instruments will now require them.
|
||||
|
||||
Please note: XP gain has pretty much been overhauled. You may need tweak the multiplier rules for your server.
|
||||
@@ -6593,7 +6472,7 @@ AndMetal: Augments are now visible when linking items.
|
||||
Trevius: SoF - Adjusted the new Item Structure to align more fields
|
||||
Trevius: SoF - Added OP_Consume and OP_LootRequest opcodes
|
||||
cavedude00: (AndMetal) AAs now use skill_id instead of index for prereqs.
|
||||
cavedude00: (mackal) Implemented Improved Instrument Mastery, Improved Singing Mastery, and Echo of Taelosia AAs.
|
||||
cavedude00: (demonstar55) Implemented Improved Instrument Mastery, Improved Singing Mastery, and Echo of Taelosia AAs.
|
||||
cavedude00: Created Combat:ChanceToHitDivideBy rule and increased default value to 1250.
|
||||
Required and Optional SQL: utils/sql/svn/326_aas.sql
|
||||
KLS: SoF - Fix for item slots in bags.
|
||||
|
||||
+24
-8
@@ -35,11 +35,9 @@ SET(common_sources
|
||||
faction.cpp
|
||||
guild_base.cpp
|
||||
guilds.cpp
|
||||
inventory_profile.cpp
|
||||
inventory_slot.cpp
|
||||
ipc_mutex.cpp
|
||||
item_data.cpp
|
||||
item_instance.cpp
|
||||
item.cpp
|
||||
item_base.cpp
|
||||
light_source.cpp
|
||||
md5.cpp
|
||||
memory_buffer.cpp
|
||||
@@ -74,7 +72,9 @@ SET(common_sources
|
||||
timeoutmgr.cpp
|
||||
timer.cpp
|
||||
unix.cpp
|
||||
uuid.cpp
|
||||
worldconn.cpp
|
||||
web_interface_utils.cpp
|
||||
xml_parser.cpp
|
||||
platform.cpp
|
||||
patches/patches.cpp
|
||||
@@ -157,12 +157,10 @@ SET(common_headers
|
||||
global_define.h
|
||||
guild_base.h
|
||||
guilds.h
|
||||
inventory_profile.h
|
||||
inventory_slot.h
|
||||
ipc_mutex.h
|
||||
item_data.h
|
||||
item.h
|
||||
item_base.h
|
||||
item_fieldlist.h
|
||||
item_instance.h
|
||||
languages.h
|
||||
light_source.h
|
||||
linked_list.h
|
||||
@@ -209,36 +207,46 @@ SET(common_headers
|
||||
timer.h
|
||||
types.h
|
||||
unix.h
|
||||
uuid.h
|
||||
useperl.h
|
||||
version.h
|
||||
worldconn.h
|
||||
web_interface_utils.h
|
||||
xml_parser.h
|
||||
zone_numbers.h
|
||||
patches/patches.h
|
||||
patches/sod.h
|
||||
# patches/sod_itemfields.h
|
||||
patches/sod_limits.h
|
||||
patches/sod_ops.h
|
||||
patches/sod_structs.h
|
||||
patches/sof.h
|
||||
# patches/sof_itemfields.h
|
||||
patches/sof_limits.h
|
||||
# patches/sof_opcode_list.h
|
||||
patches/sof_ops.h
|
||||
patches/sof_structs.h
|
||||
patches/ss_declare.h
|
||||
patches/ss_define.h
|
||||
patches/ss_register.h
|
||||
patches/rof.h
|
||||
# patches/rof_itemfields.h
|
||||
patches/rof_limits.h
|
||||
patches/rof_ops.h
|
||||
patches/rof_structs.h
|
||||
patches/rof2.h
|
||||
# patches/rof2_itemfields.h
|
||||
patches/rof2_limits.h
|
||||
patches/rof2_ops.h
|
||||
patches/rof2_structs.h
|
||||
patches/titanium.h
|
||||
# patches/titanium_itemfields_a.h
|
||||
# patches/titanium_itemfields_b.h
|
||||
patches/titanium_limits.h
|
||||
patches/titanium_ops.h
|
||||
patches/titanium_structs.h
|
||||
patches/uf.h
|
||||
# patches/uf_itemfields.h
|
||||
patches/uf_limits.h
|
||||
patches/uf_ops.h
|
||||
patches/uf_structs.h
|
||||
@@ -262,29 +270,37 @@ SET(common_headers
|
||||
SOURCE_GROUP(Patches FILES
|
||||
patches/patches.h
|
||||
patches/sod.h
|
||||
# patches/sod_itemfields.h
|
||||
patches/sod_limits.h
|
||||
patches/sod_ops.h
|
||||
patches/sod_structs.h
|
||||
patches/sof.h
|
||||
# patches/sof_itemfields.h
|
||||
patches/sof_limits.h
|
||||
# patches/sof_opcode_list.h
|
||||
patches/sof_ops.h
|
||||
patches/sof_structs.h
|
||||
patches/ss_declare.h
|
||||
patches/ss_define.h
|
||||
patches/ss_register.h
|
||||
patches/rof.h
|
||||
# patches/rof_itemfields.h
|
||||
patches/rof_limits.h
|
||||
patches/rof_ops.h
|
||||
patches/rof_structs.h
|
||||
patches/rof2.h
|
||||
# patches/rof2_itemfields.h
|
||||
patches/rof2_limits.h
|
||||
patches/rof2_ops.h
|
||||
patches/rof2_structs.h
|
||||
patches/titanium.h
|
||||
# patches/titanium_itemfields_a.h
|
||||
# patches/titanium_itemfields_b.h
|
||||
patches/titanium_limits.h
|
||||
patches/titanium_ops.h
|
||||
patches/titanium_structs.h
|
||||
patches/uf.h
|
||||
# patches/uf_itemfields.h
|
||||
patches/uf_limits.h
|
||||
patches/uf_ops.h
|
||||
patches/uf_structs.h
|
||||
|
||||
+3
-34
@@ -638,13 +638,6 @@ bool Database::SaveCharacterCreate(uint32 character_id, uint32 account_id, Playe
|
||||
character_id, pp->binds[4].zoneId, 0, pp->binds[4].x, pp->binds[4].y, pp->binds[4].z, pp->binds[4].heading, 4
|
||||
); results = QueryDatabase(query);
|
||||
|
||||
/* HoTT Ability */
|
||||
if(RuleB(Character, GrantHoTTOnCreate))
|
||||
{
|
||||
query = StringFormat("INSERT INTO `character_leadership_abilities` (id, slot, rank) VALUES (%u, %i, %i)", character_id, 14, 1);
|
||||
results = QueryDatabase(query);
|
||||
}
|
||||
|
||||
/* Save Skills */
|
||||
int firstquery = 0;
|
||||
for (int i = 0; i < MAX_PP_SKILL; i++){
|
||||
@@ -679,7 +672,7 @@ bool Database::SaveCharacterCreate(uint32 character_id, uint32 account_id, Playe
|
||||
}
|
||||
|
||||
/* This only for new Character creation storing */
|
||||
bool Database::StoreCharacter(uint32 account_id, PlayerProfile_Struct* pp, EQEmu::InventoryProfile* inv) {
|
||||
bool Database::StoreCharacter(uint32 account_id, PlayerProfile_Struct* pp, Inventory* inv) {
|
||||
uint32 charid = 0;
|
||||
char zone[50];
|
||||
float x, y, z;
|
||||
@@ -708,7 +701,7 @@ bool Database::StoreCharacter(uint32 account_id, PlayerProfile_Struct* pp, EQEmu
|
||||
/* Insert starting inventory... */
|
||||
std::string invquery;
|
||||
for (int16 i = EQEmu::legacy::EQUIPMENT_BEGIN; i <= EQEmu::legacy::BANK_BAGS_END;) {
|
||||
const EQEmu::ItemInstance* newinv = inv->GetItem(i);
|
||||
const ItemInst* newinv = inv->GetItem(i);
|
||||
if (newinv) {
|
||||
invquery = StringFormat("INSERT INTO `inventory` (charid, slotid, itemid, charges, color) VALUES (%u, %i, %u, %i, %u)",
|
||||
charid, i, newinv->GetItem()->ID, newinv->GetCharges(), newinv->GetColor());
|
||||
@@ -716,7 +709,7 @@ bool Database::StoreCharacter(uint32 account_id, PlayerProfile_Struct* pp, EQEmu
|
||||
auto results = QueryDatabase(invquery);
|
||||
}
|
||||
|
||||
if (i == EQEmu::inventory::slotCursor) {
|
||||
if (i == EQEmu::legacy::SlotCursor) {
|
||||
i = EQEmu::legacy::GENERAL_BAGS_BEGIN;
|
||||
continue;
|
||||
}
|
||||
@@ -2143,27 +2136,3 @@ bool Database::SaveTime(int8 minute, int8 hour, int8 day, int8 month, int16 year
|
||||
return results.Success();
|
||||
|
||||
}
|
||||
|
||||
int Database::GetIPExemption(std::string account_ip) {
|
||||
std::string query = StringFormat("SELECT `exemption_amount` FROM `ip_exemptions` WHERE `exemption_ip` = '%s'", account_ip.c_str());
|
||||
auto results = QueryDatabase(query);
|
||||
|
||||
if (results.Success() && results.RowCount() > 0) {
|
||||
auto row = results.begin();
|
||||
return atoi(row[0]);
|
||||
}
|
||||
|
||||
return RuleI(World, MaxClientsPerIP);
|
||||
}
|
||||
|
||||
int Database::GetInstanceID(uint32 char_id, uint32 zone_id) {
|
||||
std::string query = StringFormat("SELECT instance_list.id FROM instance_list INNER JOIN instance_list_player ON instance_list.id = instance_list_player.id WHERE instance_list.zone = '%i' AND instance_list_player.charid = '%i'", zone_id, char_id);
|
||||
auto results = QueryDatabase(query);
|
||||
|
||||
if (results.Success() && results.RowCount() > 0) {
|
||||
auto row = results.begin();
|
||||
return atoi(row[0]);;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
+2
-10
@@ -37,14 +37,10 @@
|
||||
//atoi is not uint32 or uint32 safe!!!!
|
||||
#define atoul(str) strtoul(str, nullptr, 10)
|
||||
|
||||
class Inventory;
|
||||
class MySQLRequestResult;
|
||||
class Client;
|
||||
|
||||
namespace EQEmu
|
||||
{
|
||||
class InventoryProfile;
|
||||
}
|
||||
|
||||
struct EventLogDetails_Struct {
|
||||
uint32 id;
|
||||
char accountname[64];
|
||||
@@ -113,7 +109,7 @@ public:
|
||||
bool SaveCharacterCreate(uint32 character_id, uint32 account_id, PlayerProfile_Struct* pp);
|
||||
bool SetHackerFlag(const char* accountname, const char* charactername, const char* hacked);
|
||||
bool SetMQDetectionFlag(const char* accountname, const char* charactername, const char* hacked, const char* zone);
|
||||
bool StoreCharacter(uint32 account_id, PlayerProfile_Struct* pp, EQEmu::InventoryProfile* inv);
|
||||
bool StoreCharacter(uint32 account_id, PlayerProfile_Struct* pp, Inventory* inv);
|
||||
bool UpdateName(const char* oldname, const char* newname);
|
||||
|
||||
/* General Information Queries */
|
||||
@@ -190,10 +186,6 @@ public:
|
||||
|
||||
void GetAccountFromID(uint32 id, char* oAccountName, int16* oStatus);
|
||||
void SetAgreementFlag(uint32 acctid);
|
||||
|
||||
int GetIPExemption(std::string account_ip);
|
||||
|
||||
int GetInstanceID(uint32 char_id, uint32 zone_id);
|
||||
|
||||
|
||||
/* Groups */
|
||||
|
||||
@@ -186,7 +186,7 @@ namespace Convert {
|
||||
/*002*/ uint32 HP;
|
||||
/*006*/ uint32 Mana;
|
||||
/*010*/ Convert::SpellBuff_Struct Buffs[BUFF_COUNT];
|
||||
/*510*/ uint32 Items[EQEmu::textures::materialCount];
|
||||
/*510*/ uint32 Items[EQEmu::textures::TextureCount];
|
||||
/*546*/ char Name[64];
|
||||
/*610*/
|
||||
};
|
||||
@@ -227,9 +227,9 @@ namespace Convert {
|
||||
/*0304*/ uint8 ability_time_minutes;
|
||||
/*0305*/ uint8 ability_time_hours; //place holder
|
||||
/*0306*/ uint8 unknown0306[6]; // @bp Spacer/Flag?
|
||||
/*0312*/ uint32 item_material[EQEmu::textures::materialCount]; // Item texture/material of worn/held items
|
||||
/*0312*/ uint32 item_material[EQEmu::textures::TextureCount]; // Item texture/material of worn/held items
|
||||
/*0348*/ uint8 unknown0348[44];
|
||||
/*0392*/ Convert::Color_Struct item_tint[EQEmu::textures::materialCount];
|
||||
/*0392*/ Convert::Color_Struct item_tint[EQEmu::textures::TextureCount];
|
||||
/*0428*/ Convert::AA_Array aa_array[MAX_PP_AA_ARRAY];
|
||||
/*2348*/ float unknown2384; //seen ~128, ~47
|
||||
/*2352*/ char servername[32]; // length probably not right
|
||||
@@ -472,18 +472,31 @@ bool Database::CheckDatabaseConversions() {
|
||||
CheckDatabaseConvertPPDeblob();
|
||||
CheckDatabaseConvertCorpseDeblob();
|
||||
|
||||
/* Fetch EQEmu Server script */
|
||||
if (!std::ifstream("eqemu_server.pl")){
|
||||
/* Fetch Automatic Upgrade Script */
|
||||
if (!std::ifstream("eqemu_update.pl")){
|
||||
std::cout << "Pulling down automatic database upgrade script..." << std::endl;
|
||||
#ifdef _WIN32
|
||||
system("perl -MLWP::UserAgent -e \"require LWP::UserAgent; my $ua = LWP::UserAgent->new; $ua->timeout(10); $ua->env_proxy; my $response = $ua->get('https://raw.githubusercontent.com/EQEmu/Server/master/utils/scripts/eqemu_server.pl'); if ($response->is_success){ open(FILE, '> eqemu_server.pl'); print FILE $response->decoded_content; close(FILE); }\"");
|
||||
system("perl -MLWP::UserAgent -e \"require LWP::UserAgent; my $ua = LWP::UserAgent->new; $ua->timeout(10); $ua->env_proxy; my $response = $ua->get('https://raw.githubusercontent.com/EQEmu/Server/master/utils/scripts/eqemu_update.pl'); if ($response->is_success){ open(FILE, '> eqemu_update.pl'); print FILE $response->decoded_content; close(FILE); }\"");
|
||||
#else
|
||||
system("wget --no-check-certificate -O eqemu_server.pl https://raw.githubusercontent.com/EQEmu/Server/master/utils/scripts/eqemu_server.pl");
|
||||
system("wget --no-check-certificate -O eqemu_update.pl https://raw.githubusercontent.com/EQEmu/Server/master/utils/scripts/eqemu_update.pl");
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Run EQEmu Server script (Checks for database updates) */
|
||||
system("perl eqemu_server.pl ran_from_world");
|
||||
/*
|
||||
Automatic (Database) Upgrade Script
|
||||
Script: eqemu_update.pl V 1 - the number that world passes to the script will
|
||||
force the script to check for a newer version to update itself with
|
||||
eqemu_update.pl ran_from_world - won't bring up a menu if your database versions match
|
||||
eqemu_update.pl - ran standalone will bring up a menu prompt
|
||||
*/
|
||||
|
||||
/* Check for a new version of this script, the arg passed
|
||||
would have to be higher than the copy they have downloaded
|
||||
locally and they will re fetch */
|
||||
system("perl eqemu_update.pl V 14");
|
||||
|
||||
/* Run Automatic Database Upgrade Script */
|
||||
system("perl eqemu_update.pl ran_from_world");
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -1403,7 +1416,7 @@ bool Database::CheckDatabaseConvertPPDeblob(){
|
||||
if (rquery != ""){ results = QueryDatabase(rquery); }
|
||||
/* Run Material Color Convert */
|
||||
first_entry = 0; rquery = "";
|
||||
for (i = EQEmu::textures::textureBegin; i < EQEmu::textures::materialCount; i++){
|
||||
for (i = 0; i < EQEmu::textures::TextureCount; i++){
|
||||
if (pp->item_tint[i].color > 0){
|
||||
if (first_entry != 1){
|
||||
rquery = StringFormat("REPLACE INTO `character_material` (id, slot, blue, green, red, use_tint, color) VALUES (%u, %u, %u, %u, %u, %u, %u)", character_id, i, pp->item_tint[i].rgb.blue, pp->item_tint[i].rgb.green, pp->item_tint[i].rgb.red, pp->item_tint[i].rgb.use_tint, pp->item_tint[i].color);
|
||||
|
||||
@@ -35,79 +35,6 @@ namespace EQEmu
|
||||
//using namespace RoF2::invbag;
|
||||
//using namespace RoF2::invaug;
|
||||
|
||||
enum : int16 { typeInvalid = -1, slotInvalid = -1, containerInvalid = -1, socketInvalid = -1 }; // temporary
|
||||
enum : int16 { typeBegin = 0, slotBegin = 0, containerBegin = 0, socketBegin = 0 }; // temporary
|
||||
|
||||
enum PossessionsSlots : int16 { // temporary
|
||||
slotCharm = 0,
|
||||
slotEar1,
|
||||
slotHead,
|
||||
slotFace,
|
||||
slotEar2,
|
||||
slotNeck, // 5
|
||||
slotShoulders,
|
||||
slotArms,
|
||||
slotBack,
|
||||
slotWrist1,
|
||||
slotWrist2, // 10
|
||||
slotRange,
|
||||
slotHands,
|
||||
slotPrimary,
|
||||
slotSecondary,
|
||||
slotFinger1, // 15
|
||||
slotFinger2,
|
||||
slotChest,
|
||||
slotLegs,
|
||||
slotFeet,
|
||||
slotWaist, // 20
|
||||
slotPowerSource = 9999,
|
||||
slotAmmo = 21,
|
||||
slotGeneral1,
|
||||
slotGeneral2,
|
||||
slotGeneral3,
|
||||
slotGeneral4, // 25
|
||||
slotGeneral5,
|
||||
slotGeneral6,
|
||||
slotGeneral7,
|
||||
slotGeneral8,
|
||||
slotCursor, // 30
|
||||
slotCount
|
||||
};
|
||||
|
||||
enum InventoryTypes : int16 { // temporary
|
||||
typePossessions = 0,
|
||||
typeBank,
|
||||
typeSharedBank,
|
||||
typeTrade,
|
||||
typeWorld,
|
||||
typeLimbo, // 5
|
||||
typeTribute,
|
||||
typeTrophyTribute,
|
||||
typeGuildTribute,
|
||||
typeMerchant,
|
||||
typeDeleted, // 10
|
||||
typeCorpse,
|
||||
typeBazaar,
|
||||
typeInspect,
|
||||
typeRealEstate,
|
||||
typeViewMODPC, // 15
|
||||
typeViewMODBank,
|
||||
typeViewMODSharedBank,
|
||||
typeViewMODLimbo,
|
||||
typeAltStorage,
|
||||
typeArchived, // 20
|
||||
typeMail,
|
||||
typeGuildTrophyTribute,
|
||||
typeKrono,
|
||||
typeOther,
|
||||
typeCount
|
||||
};
|
||||
|
||||
static int16 SlotCount(int16 type_index) { return 0; } // temporary
|
||||
|
||||
const int16 ContainerCount = 10; // temporary
|
||||
const int16 SocketCount = 6; // temporary
|
||||
|
||||
} /*inventory*/
|
||||
|
||||
namespace constants {
|
||||
@@ -116,16 +43,7 @@ namespace EQEmu
|
||||
|
||||
const size_t SayLinkBodySize = RoF2::constants::SayLinkBodySize;
|
||||
|
||||
const int LongBuffs = RoF2::constants::LongBuffs;
|
||||
const int ShortBuffs = RoF2::constants::ShortBuffs;
|
||||
const int DiscBuffs = RoF2::constants::DiscBuffs;
|
||||
const int TotalBuffs = RoF2::constants::TotalBuffs;
|
||||
const int NPCBuffs = RoF2::constants::NPCBuffs;
|
||||
const int PetBuffs = RoF2::constants::PetBuffs;
|
||||
const int MercBuffs = RoF2::constants::MercBuffs;
|
||||
|
||||
} /*constants*/
|
||||
|
||||
enum class CastingSlot : uint32 {
|
||||
Gem1 = 0,
|
||||
Gem2 = 1,
|
||||
@@ -150,9 +68,3 @@ namespace EQEmu
|
||||
} /*EQEmu*/
|
||||
|
||||
#endif /*COMMON_EMU_CONSTANTS_H*/
|
||||
|
||||
/* hack list to prevent circular references
|
||||
|
||||
eq_limits.h:EQEmu::inventory::LookupEntry::InventoryTypeSize[n];
|
||||
|
||||
*/
|
||||
|
||||
+89
-15
@@ -61,6 +61,8 @@ namespace EQEmu
|
||||
SLOT_GENERAL_6 = 27,
|
||||
SLOT_GENERAL_7 = 28,
|
||||
SLOT_GENERAL_8 = 29,
|
||||
//SLOT_GENERAL_9 = not supported
|
||||
//SLOT_GENERAL_10 = not supported
|
||||
SLOT_CURSOR = 30,
|
||||
SLOT_CURSOR_END = (int16)0xFFFE, // I hope no one is using this...
|
||||
SLOT_TRADESKILL = 1000,
|
||||
@@ -94,8 +96,75 @@ namespace EQEmu
|
||||
SLOT_WORLD_END = 4009
|
||||
};
|
||||
|
||||
enum InventoryTypes : int16 {
|
||||
TypePossessions = 0,
|
||||
TypeBank,
|
||||
TypeSharedBank,
|
||||
TypeTrade,
|
||||
TypeWorld,
|
||||
TypeLimbo, // 5
|
||||
TypeTribute,
|
||||
TypeTrophyTribute,
|
||||
TypeGuildTribute,
|
||||
TypeMerchant,
|
||||
TypeDeleted, // 10
|
||||
TypeCorpse,
|
||||
TypeBazaar,
|
||||
TypeInspect,
|
||||
TypeRealEstate,
|
||||
TypeViewMODPC, // 15
|
||||
TypeViewMODBank,
|
||||
TypeViewMODSharedBank,
|
||||
TypeViewMODLimbo,
|
||||
TypeAltStorage,
|
||||
TypeArchived, // 20
|
||||
TypeMail,
|
||||
TypeGuildTrophyTribute,
|
||||
TypeKrono,
|
||||
TypeOther,
|
||||
TypeCount
|
||||
};
|
||||
|
||||
enum PossessionsSlots : int16 {
|
||||
SlotCharm = 0,
|
||||
SlotEar1,
|
||||
SlotHead,
|
||||
SlotFace,
|
||||
SlotEar2,
|
||||
SlotNeck, // 5
|
||||
SlotShoulders,
|
||||
SlotArms,
|
||||
SlotBack,
|
||||
SlotWrist1,
|
||||
SlotWrist2, // 10
|
||||
SlotRange,
|
||||
SlotHands,
|
||||
SlotPrimary,
|
||||
SlotSecondary,
|
||||
SlotFinger1, // 15
|
||||
SlotFinger2,
|
||||
SlotChest,
|
||||
SlotLegs,
|
||||
SlotFeet,
|
||||
SlotWaist, // 20
|
||||
SlotPowerSource = 9999, // temp
|
||||
SlotAmmo = 21, // temp
|
||||
SlotGeneral1,
|
||||
SlotGeneral2,
|
||||
SlotGeneral3,
|
||||
SlotGeneral4, // 25
|
||||
SlotGeneral5,
|
||||
SlotGeneral6,
|
||||
SlotGeneral7,
|
||||
SlotGeneral8,
|
||||
//SlotGeneral9,
|
||||
//SlotGeneral10,
|
||||
SlotCursor, // 30
|
||||
SlotCount
|
||||
};
|
||||
|
||||
// these are currently hard-coded for existing inventory system..do not use in place of special client version handlers until ready
|
||||
static const uint16 TYPE_POSSESSIONS_SIZE = 31;
|
||||
static const uint16 TYPE_POSSESSIONS_SIZE = SlotCount;
|
||||
static const uint16 TYPE_BANK_SIZE = 24;
|
||||
static const uint16 TYPE_SHARED_BANK_SIZE = 2;
|
||||
static const uint16 TYPE_TRADE_SIZE = 8;
|
||||
@@ -106,14 +175,14 @@ namespace EQEmu
|
||||
static const uint16 TYPE_GUILD_TRIBUTE_SIZE = 0;
|
||||
static const uint16 TYPE_MERCHANT_SIZE = 0;
|
||||
static const uint16 TYPE_DELETED_SIZE = 0;
|
||||
static const uint16 TYPE_CORPSE_SIZE = 31; // no bitmask use..limits to size of client corpse window (see EQLimits::InventoryMapSize(MapCorpse, <EQClientVersion))
|
||||
static const uint16 TYPE_CORPSE_SIZE = SlotCount; // no bitmask use..limits to size of client corpse window (see EQLimits::InventoryMapSize(MapCorpse, <EQClientVersion))
|
||||
static const uint16 TYPE_BAZAAR_SIZE = 80;
|
||||
static const uint16 TYPE_INSPECT_SIZE = 22;
|
||||
static const uint16 TYPE_REAL_ESTATE_SIZE = 0;
|
||||
static const uint16 TYPE_VIEW_MOD_PC_SIZE = 0;
|
||||
static const uint16 TYPE_VIEW_MOD_BANK_SIZE = 0;
|
||||
static const uint16 TYPE_VIEW_MOD_SHARED_BANK_SIZE = 0;
|
||||
static const uint16 TYPE_VIEW_MOD_LIMBO_SIZE = 0;
|
||||
static const uint16 TYPE_VIEW_MOD_PC_SIZE = 0;//NOT_USED;
|
||||
static const uint16 TYPE_VIEW_MOD_BANK_SIZE = 0;//NOT_USED;
|
||||
static const uint16 TYPE_VIEW_MOD_SHARED_BANK_SIZE = 0;//NOT_USED;
|
||||
static const uint16 TYPE_VIEW_MOD_LIMBO_SIZE = 0;//NOT_USED;
|
||||
static const uint16 TYPE_ALT_STORAGE_SIZE = 0;
|
||||
static const uint16 TYPE_ARCHIVED_SIZE = 0;
|
||||
static const uint16 TYPE_MAIL_SIZE = 0;
|
||||
@@ -123,12 +192,12 @@ namespace EQEmu
|
||||
|
||||
// most of these definitions will go away with the structure-based system..this maintains compatibility for now
|
||||
// (these are mainly to assign specific values to constants used in conversions and to identify per-client ranges/offsets)
|
||||
static const int16 EQUIPMENT_BEGIN = 0;
|
||||
static const int16 EQUIPMENT_END = 21;
|
||||
static const int16 EQUIPMENT_BEGIN = SlotCharm;
|
||||
static const int16 EQUIPMENT_END = SlotAmmo;
|
||||
static const uint16 EQUIPMENT_SIZE = 22; // does not account for 'Power Source' - used mainly for npc equipment arrays
|
||||
|
||||
static const int16 GENERAL_BEGIN = 22;
|
||||
static const int16 GENERAL_END = 29;
|
||||
static const int16 GENERAL_BEGIN = SlotGeneral1;
|
||||
static const int16 GENERAL_END = SlotGeneral8;
|
||||
static const uint16 GENERAL_SIZE = 8;
|
||||
static const int16 GENERAL_BAGS_BEGIN = 251;
|
||||
static const int16 GENERAL_BAGS_END_OFFSET = 79;
|
||||
@@ -166,17 +235,22 @@ namespace EQEmu
|
||||
static const int16 TRIBUTE_SIZE = TYPE_TRIBUTE_SIZE;
|
||||
|
||||
static const int16 CORPSE_BEGIN = 22;
|
||||
//static const int16 CORPSE_END = RoF::consts::CORPSE_END; // not ready for use
|
||||
|
||||
// items
|
||||
// common and container sizes will not increase until the new 'location' struct is implemented
|
||||
static const uint16 ITEM_COMMON_SIZE = 6;//RoF::consts::ITEM_COMMON_SIZE;
|
||||
static const uint16 ITEM_CONTAINER_SIZE = 10;//Titanium::consts::ITEM_CONTAINER_SIZE;
|
||||
|
||||
// BANDOLIERS_SIZE sets maximum limit..active limit will need to be handled by the appropriate AA or spell (or item?)
|
||||
static const size_t BANDOLIERS_SIZE = 20; // number of bandolier instances
|
||||
static const size_t BANDOLIER_ITEM_COUNT = 4; // number of equipment slots in bandolier instance
|
||||
static const size_t BANDOLIERS_SIZE = 20;//RoF2::consts::BANDOLIERS_SIZE; // number of bandolier instances
|
||||
static const size_t BANDOLIER_ITEM_COUNT = 4;//RoF2::consts::BANDOLIER_ITEM_COUNT; // number of equipment slots in bandolier instance
|
||||
|
||||
// POTION_BELT_SIZE sets maximum limit..active limit will need to be handled by the appropriate AA or spell (or item?)
|
||||
static const size_t POTION_BELT_ITEM_COUNT = 5;
|
||||
static const size_t POTION_BELT_ITEM_COUNT = 5;//RoF2::consts::POTION_BELT_ITEM_COUNT;
|
||||
|
||||
static const size_t TEXT_LINK_BODY_LENGTH = 56;
|
||||
static const size_t TEXT_LINK_BODY_LENGTH = 56;//RoF2::consts::TEXT_LINK_BODY_LENGTH;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif /* COMMON_EMU_LEGACY_H */
|
||||
|
||||
@@ -363,6 +363,22 @@ bool EmuTCPConnection::LineOutQueuePush(char* line) {
|
||||
safe_delete_array(line);
|
||||
return(true);
|
||||
}
|
||||
if (strcmp(line, "**PACKETMODEWI**") == 0) {
|
||||
MSendQueue.lock();
|
||||
safe_delete_array(sendbuf);
|
||||
if (TCPMode == modeConsole)
|
||||
Send((const uchar*) "\0**PACKETMODEWI**\r", 18);
|
||||
TCPMode = modePacket;
|
||||
PacketMode = packetModeWebInterface;
|
||||
EmuTCPNetPacket_Struct* tnps = 0;
|
||||
while ((tnps = InModeQueue.pop())) {
|
||||
SendPacket(tnps);
|
||||
safe_delete_array(tnps);
|
||||
}
|
||||
MSendQueue.unlock();
|
||||
safe_delete_array(line);
|
||||
return(true);
|
||||
}
|
||||
}
|
||||
|
||||
return(TCPConnection::LineOutQueuePush(line));
|
||||
@@ -416,6 +432,13 @@ bool EmuTCPConnection::ConnectIP(uint32 irIP, uint16 irPort, char* errbuf) {
|
||||
sendbuf = new uchar[sendbuf_size];
|
||||
memcpy(sendbuf, "\0**PACKETMODEQS**\r", sendbuf_size);
|
||||
}
|
||||
else if (PacketMode == packetModeWebInterface) {
|
||||
safe_delete_array(sendbuf);
|
||||
sendbuf_size = 18;
|
||||
sendbuf_used = sendbuf_size;
|
||||
sendbuf = new uchar[sendbuf_size];
|
||||
memcpy(sendbuf, "\0**PACKETMODEWI**\r", sendbuf_size);
|
||||
}
|
||||
else {
|
||||
//default: packetModeZone
|
||||
safe_delete_array(sendbuf);
|
||||
|
||||
@@ -31,7 +31,7 @@ class ServerPacket;
|
||||
class EmuTCPConnection : public TCPConnection {
|
||||
public:
|
||||
enum eTCPMode { modeConsole, modeTransition, modePacket };
|
||||
enum ePacketMode { packetModeZone, packetModeLauncher, packetModeLogin, packetModeUCS, packetModeQueryServ };
|
||||
enum ePacketMode { packetModeZone, packetModeLauncher, packetModeLogin, packetModeUCS, packetModeQueryServ, packetModeWebInterface };
|
||||
|
||||
EmuTCPConnection(uint32 ID, EmuTCPServer* iServer, SOCKET iSock, uint32 irIP, uint16 irPort, bool iOldFormat = false);
|
||||
EmuTCPConnection(bool iOldFormat = false, EmuTCPServer* iRelayServer = 0, eTCPMode iMode = modePacket); // for outgoing connections
|
||||
|
||||
+113
-113
@@ -127,244 +127,244 @@ uint32 EQEmu::versions::ConvertClientVersionToExpansion(ClientVersion client_ver
|
||||
}
|
||||
}
|
||||
|
||||
bool EQEmu::versions::IsValidMobVersion(MobVersion mob_version)
|
||||
bool EQEmu::versions::IsValidInventoryVersion(InventoryVersion inventory_version)
|
||||
{
|
||||
if (mob_version <= MobVersion::Unknown || mob_version > LastMobVersion)
|
||||
if (inventory_version <= InventoryVersion::Unknown || inventory_version > LastInventoryVersion)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool EQEmu::versions::IsValidPCMobVersion(MobVersion mob_version)
|
||||
bool EQEmu::versions::IsValidPCInventoryVersion(InventoryVersion inventory_version)
|
||||
{
|
||||
if (mob_version <= MobVersion::Unknown || mob_version > LastPCMobVersion)
|
||||
if (inventory_version <= InventoryVersion::Unknown || inventory_version > LastPCInventoryVersion)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool EQEmu::versions::IsValidNonPCMobVersion(MobVersion mob_version)
|
||||
bool EQEmu::versions::IsValidNonPCInventoryVersion(InventoryVersion inventory_version)
|
||||
{
|
||||
if (mob_version <= LastPCMobVersion || mob_version > LastNonPCMobVersion)
|
||||
if (inventory_version <= LastPCInventoryVersion || inventory_version > LastNonPCInventoryVersion)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool EQEmu::versions::IsValidOfflinePCMobVersion(MobVersion mob_version)
|
||||
bool EQEmu::versions::IsValidOfflinePCInventoryVersion(InventoryVersion inventory_version)
|
||||
{
|
||||
if (mob_version <= LastNonPCMobVersion || mob_version > LastOfflinePCMobVersion)
|
||||
if (inventory_version <= LastNonPCInventoryVersion || inventory_version > LastOfflinePCInventoryVersion)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
EQEmu::versions::MobVersion EQEmu::versions::ValidateMobVersion(MobVersion mob_version)
|
||||
EQEmu::versions::InventoryVersion EQEmu::versions::ValidateInventoryVersion(InventoryVersion inventory_version)
|
||||
{
|
||||
if (mob_version <= MobVersion::Unknown || mob_version > LastMobVersion)
|
||||
return MobVersion::Unknown;
|
||||
if (inventory_version <= InventoryVersion::Unknown || inventory_version > LastInventoryVersion)
|
||||
return InventoryVersion::Unknown;
|
||||
|
||||
return mob_version;
|
||||
return inventory_version;
|
||||
}
|
||||
|
||||
EQEmu::versions::MobVersion EQEmu::versions::ValidatePCMobVersion(MobVersion mob_version)
|
||||
EQEmu::versions::InventoryVersion EQEmu::versions::ValidatePCInventoryVersion(InventoryVersion inventory_version)
|
||||
{
|
||||
if (mob_version <= MobVersion::Unknown || mob_version > LastPCMobVersion)
|
||||
return MobVersion::Unknown;
|
||||
if (inventory_version <= InventoryVersion::Unknown || inventory_version > LastPCInventoryVersion)
|
||||
return InventoryVersion::Unknown;
|
||||
|
||||
return mob_version;
|
||||
return inventory_version;
|
||||
}
|
||||
|
||||
EQEmu::versions::MobVersion EQEmu::versions::ValidateNonPCMobVersion(MobVersion mob_version)
|
||||
EQEmu::versions::InventoryVersion EQEmu::versions::ValidateNonPCInventoryVersion(InventoryVersion inventory_version)
|
||||
{
|
||||
if (mob_version <= LastPCMobVersion || mob_version > LastNonPCMobVersion)
|
||||
return MobVersion::Unknown;
|
||||
if (inventory_version <= LastPCInventoryVersion || inventory_version > LastNonPCInventoryVersion)
|
||||
return InventoryVersion::Unknown;
|
||||
|
||||
return mob_version;
|
||||
return inventory_version;
|
||||
}
|
||||
|
||||
EQEmu::versions::MobVersion EQEmu::versions::ValidateOfflinePCMobVersion(MobVersion mob_version)
|
||||
EQEmu::versions::InventoryVersion EQEmu::versions::ValidateOfflinePCInventoryVersion(InventoryVersion inventory_version)
|
||||
{
|
||||
if (mob_version <= LastNonPCMobVersion || mob_version > LastOfflinePCMobVersion)
|
||||
return MobVersion::Unknown;
|
||||
if (inventory_version <= LastNonPCInventoryVersion || inventory_version > LastOfflinePCInventoryVersion)
|
||||
return InventoryVersion::Unknown;
|
||||
|
||||
return mob_version;
|
||||
return inventory_version;
|
||||
}
|
||||
|
||||
const char* EQEmu::versions::MobVersionName(MobVersion mob_version)
|
||||
const char* EQEmu::versions::InventoryVersionName(InventoryVersion inventory_version)
|
||||
{
|
||||
switch (mob_version) {
|
||||
case MobVersion::Unknown:
|
||||
switch (inventory_version) {
|
||||
case InventoryVersion::Unknown:
|
||||
return "Unknown Version";
|
||||
case MobVersion::Client62:
|
||||
case InventoryVersion::Client62:
|
||||
return "Client 6.2";
|
||||
case MobVersion::Titanium:
|
||||
case InventoryVersion::Titanium:
|
||||
return "Titanium";
|
||||
case MobVersion::SoF:
|
||||
case InventoryVersion::SoF:
|
||||
return "SoF";
|
||||
case MobVersion::SoD:
|
||||
case InventoryVersion::SoD:
|
||||
return "SoD";
|
||||
case MobVersion::UF:
|
||||
case InventoryVersion::UF:
|
||||
return "UF";
|
||||
case MobVersion::RoF:
|
||||
case InventoryVersion::RoF:
|
||||
return "RoF";
|
||||
case MobVersion::RoF2:
|
||||
case InventoryVersion::RoF2:
|
||||
return "RoF2";
|
||||
case MobVersion::NPC:
|
||||
case InventoryVersion::NPC:
|
||||
return "NPC";
|
||||
case MobVersion::NPCMerchant:
|
||||
case InventoryVersion::NPCMerchant:
|
||||
return "NPC Merchant";
|
||||
case MobVersion::Merc:
|
||||
case InventoryVersion::Merc:
|
||||
return "Merc";
|
||||
case MobVersion::Bot:
|
||||
case InventoryVersion::Bot:
|
||||
return "Bot";
|
||||
case MobVersion::ClientPet:
|
||||
case InventoryVersion::ClientPet:
|
||||
return "Client Pet";
|
||||
case MobVersion::NPCPet:
|
||||
case InventoryVersion::NPCPet:
|
||||
return "NPC Pet";
|
||||
case MobVersion::MercPet:
|
||||
case InventoryVersion::MercPet:
|
||||
return "Merc Pet";
|
||||
case MobVersion::BotPet:
|
||||
case InventoryVersion::BotPet:
|
||||
return "Bot Pet";
|
||||
case MobVersion::OfflineTitanium:
|
||||
case InventoryVersion::OfflineTitanium:
|
||||
return "Offline Titanium";
|
||||
case MobVersion::OfflineSoF:
|
||||
case InventoryVersion::OfflineSoF:
|
||||
return "Offline SoF";
|
||||
case MobVersion::OfflineSoD:
|
||||
case InventoryVersion::OfflineSoD:
|
||||
return "Offline SoD";
|
||||
case MobVersion::OfflineUF:
|
||||
case InventoryVersion::OfflineUF:
|
||||
return "Offline UF";
|
||||
case MobVersion::OfflineRoF:
|
||||
case InventoryVersion::OfflineRoF:
|
||||
return "Offline RoF";
|
||||
case MobVersion::OfflineRoF2:
|
||||
case InventoryVersion::OfflineRoF2:
|
||||
return "Offline RoF2";
|
||||
default:
|
||||
return "Invalid Version";
|
||||
};
|
||||
}
|
||||
|
||||
EQEmu::versions::ClientVersion EQEmu::versions::ConvertMobVersionToClientVersion(MobVersion mob_version)
|
||||
EQEmu::versions::ClientVersion EQEmu::versions::ConvertInventoryVersionToClientVersion(InventoryVersion inventory_version)
|
||||
{
|
||||
switch (mob_version) {
|
||||
case MobVersion::Unknown:
|
||||
case MobVersion::Client62:
|
||||
switch (inventory_version) {
|
||||
case InventoryVersion::Unknown:
|
||||
case InventoryVersion::Client62:
|
||||
return ClientVersion::Unknown;
|
||||
case MobVersion::Titanium:
|
||||
case InventoryVersion::Titanium:
|
||||
return ClientVersion::Titanium;
|
||||
case MobVersion::SoF:
|
||||
case InventoryVersion::SoF:
|
||||
return ClientVersion::SoF;
|
||||
case MobVersion::SoD:
|
||||
case InventoryVersion::SoD:
|
||||
return ClientVersion::SoD;
|
||||
case MobVersion::UF:
|
||||
case InventoryVersion::UF:
|
||||
return ClientVersion::UF;
|
||||
case MobVersion::RoF:
|
||||
case InventoryVersion::RoF:
|
||||
return ClientVersion::RoF;
|
||||
case MobVersion::RoF2:
|
||||
case InventoryVersion::RoF2:
|
||||
return ClientVersion::RoF2;
|
||||
default:
|
||||
return ClientVersion::Unknown;
|
||||
}
|
||||
}
|
||||
|
||||
EQEmu::versions::MobVersion EQEmu::versions::ConvertClientVersionToMobVersion(ClientVersion client_version)
|
||||
EQEmu::versions::InventoryVersion EQEmu::versions::ConvertClientVersionToInventoryVersion(ClientVersion client_version)
|
||||
{
|
||||
switch (client_version) {
|
||||
case ClientVersion::Unknown:
|
||||
case ClientVersion::Client62:
|
||||
return MobVersion::Unknown;
|
||||
return InventoryVersion::Unknown;
|
||||
case ClientVersion::Titanium:
|
||||
return MobVersion::Titanium;
|
||||
return InventoryVersion::Titanium;
|
||||
case ClientVersion::SoF:
|
||||
return MobVersion::SoF;
|
||||
return InventoryVersion::SoF;
|
||||
case ClientVersion::SoD:
|
||||
return MobVersion::SoD;
|
||||
return InventoryVersion::SoD;
|
||||
case ClientVersion::UF:
|
||||
return MobVersion::UF;
|
||||
return InventoryVersion::UF;
|
||||
case ClientVersion::RoF:
|
||||
return MobVersion::RoF;
|
||||
return InventoryVersion::RoF;
|
||||
case ClientVersion::RoF2:
|
||||
return MobVersion::RoF2;
|
||||
return InventoryVersion::RoF2;
|
||||
default:
|
||||
return MobVersion::Unknown;
|
||||
return InventoryVersion::Unknown;
|
||||
}
|
||||
}
|
||||
|
||||
EQEmu::versions::MobVersion EQEmu::versions::ConvertPCMobVersionToOfflinePCMobVersion(MobVersion mob_version)
|
||||
EQEmu::versions::InventoryVersion EQEmu::versions::ConvertPCInventoryVersionToOfflinePCInventoryVersion(InventoryVersion inventory_version)
|
||||
{
|
||||
switch (mob_version) {
|
||||
case MobVersion::Titanium:
|
||||
return MobVersion::OfflineTitanium;
|
||||
case MobVersion::SoF:
|
||||
return MobVersion::OfflineSoF;
|
||||
case MobVersion::SoD:
|
||||
return MobVersion::OfflineSoD;
|
||||
case MobVersion::UF:
|
||||
return MobVersion::OfflineUF;
|
||||
case MobVersion::RoF:
|
||||
return MobVersion::OfflineRoF;
|
||||
case MobVersion::RoF2:
|
||||
return MobVersion::OfflineRoF2;
|
||||
switch (inventory_version) {
|
||||
case InventoryVersion::Titanium:
|
||||
return InventoryVersion::OfflineTitanium;
|
||||
case InventoryVersion::SoF:
|
||||
return InventoryVersion::OfflineSoF;
|
||||
case InventoryVersion::SoD:
|
||||
return InventoryVersion::OfflineSoD;
|
||||
case InventoryVersion::UF:
|
||||
return InventoryVersion::OfflineUF;
|
||||
case InventoryVersion::RoF:
|
||||
return InventoryVersion::OfflineRoF;
|
||||
case InventoryVersion::RoF2:
|
||||
return InventoryVersion::OfflineRoF2;
|
||||
default:
|
||||
return MobVersion::Unknown;
|
||||
return InventoryVersion::Unknown;
|
||||
}
|
||||
}
|
||||
|
||||
EQEmu::versions::MobVersion EQEmu::versions::ConvertOfflinePCMobVersionToPCMobVersion(MobVersion mob_version)
|
||||
EQEmu::versions::InventoryVersion EQEmu::versions::ConvertOfflinePCInventoryVersionToPCInventoryVersion(InventoryVersion inventory_version)
|
||||
{
|
||||
switch (mob_version) {
|
||||
case MobVersion::OfflineTitanium:
|
||||
return MobVersion::Titanium;
|
||||
case MobVersion::OfflineSoF:
|
||||
return MobVersion::SoF;
|
||||
case MobVersion::OfflineSoD:
|
||||
return MobVersion::SoD;
|
||||
case MobVersion::OfflineUF:
|
||||
return MobVersion::UF;
|
||||
case MobVersion::OfflineRoF:
|
||||
return MobVersion::RoF;
|
||||
case MobVersion::OfflineRoF2:
|
||||
return MobVersion::RoF2;
|
||||
switch (inventory_version) {
|
||||
case InventoryVersion::OfflineTitanium:
|
||||
return InventoryVersion::Titanium;
|
||||
case InventoryVersion::OfflineSoF:
|
||||
return InventoryVersion::SoF;
|
||||
case InventoryVersion::OfflineSoD:
|
||||
return InventoryVersion::SoD;
|
||||
case InventoryVersion::OfflineUF:
|
||||
return InventoryVersion::UF;
|
||||
case InventoryVersion::OfflineRoF:
|
||||
return InventoryVersion::RoF;
|
||||
case InventoryVersion::OfflineRoF2:
|
||||
return InventoryVersion::RoF2;
|
||||
default:
|
||||
return MobVersion::Unknown;
|
||||
return InventoryVersion::Unknown;
|
||||
}
|
||||
}
|
||||
|
||||
EQEmu::versions::ClientVersion EQEmu::versions::ConvertOfflinePCMobVersionToClientVersion(MobVersion mob_version)
|
||||
EQEmu::versions::ClientVersion EQEmu::versions::ConvertOfflinePCInventoryVersionToClientVersion(InventoryVersion inventory_version)
|
||||
{
|
||||
switch (mob_version) {
|
||||
case MobVersion::OfflineTitanium:
|
||||
switch (inventory_version) {
|
||||
case InventoryVersion::OfflineTitanium:
|
||||
return ClientVersion::Titanium;
|
||||
case MobVersion::OfflineSoF:
|
||||
case InventoryVersion::OfflineSoF:
|
||||
return ClientVersion::SoF;
|
||||
case MobVersion::OfflineSoD:
|
||||
case InventoryVersion::OfflineSoD:
|
||||
return ClientVersion::SoD;
|
||||
case MobVersion::OfflineUF:
|
||||
case InventoryVersion::OfflineUF:
|
||||
return ClientVersion::UF;
|
||||
case MobVersion::OfflineRoF:
|
||||
case InventoryVersion::OfflineRoF:
|
||||
return ClientVersion::RoF;
|
||||
case MobVersion::OfflineRoF2:
|
||||
case InventoryVersion::OfflineRoF2:
|
||||
return ClientVersion::RoF2;
|
||||
default:
|
||||
return ClientVersion::Unknown;
|
||||
}
|
||||
}
|
||||
|
||||
EQEmu::versions::MobVersion EQEmu::versions::ConvertClientVersionToOfflinePCMobVersion(ClientVersion client_version)
|
||||
EQEmu::versions::InventoryVersion EQEmu::versions::ConvertClientVersionToOfflinePCInventoryVersion(ClientVersion client_version)
|
||||
{
|
||||
switch (client_version) {
|
||||
case ClientVersion::Titanium:
|
||||
return MobVersion::OfflineTitanium;
|
||||
return InventoryVersion::OfflineTitanium;
|
||||
case ClientVersion::SoF:
|
||||
return MobVersion::OfflineSoF;
|
||||
return InventoryVersion::OfflineSoF;
|
||||
case ClientVersion::SoD:
|
||||
return MobVersion::OfflineSoD;
|
||||
return InventoryVersion::OfflineSoD;
|
||||
case ClientVersion::UF:
|
||||
return MobVersion::OfflineUF;
|
||||
return InventoryVersion::OfflineUF;
|
||||
case ClientVersion::RoF:
|
||||
return MobVersion::OfflineRoF;
|
||||
return InventoryVersion::OfflineRoF;
|
||||
case ClientVersion::RoF2:
|
||||
return MobVersion::OfflineRoF2;
|
||||
return InventoryVersion::OfflineRoF2;
|
||||
default:
|
||||
return MobVersion::Unknown;
|
||||
return InventoryVersion::Unknown;
|
||||
}
|
||||
}
|
||||
|
||||
+29
-27
@@ -64,15 +64,17 @@ namespace EQEmu
|
||||
const ClientVersion LastClientVersion = ClientVersion::RoF2;
|
||||
const size_t ClientVersionCount = (static_cast<size_t>(LastClientVersion) + 1);
|
||||
|
||||
bool IsValidClientVersion(ClientVersion client_version);
|
||||
ClientVersion ValidateClientVersion(ClientVersion client_version);
|
||||
const char* ClientVersionName(ClientVersion client_version);
|
||||
uint32 ConvertClientVersionToClientVersionBit(ClientVersion client_version);
|
||||
ClientVersion ConvertClientVersionBitToClientVersion(uint32 client_version_bit);
|
||||
uint32 ConvertClientVersionToExpansion(ClientVersion client_version);
|
||||
extern bool IsValidClientVersion(ClientVersion client_version);
|
||||
extern ClientVersion ValidateClientVersion(ClientVersion client_version);
|
||||
extern const char* ClientVersionName(ClientVersion client_version);
|
||||
extern uint32 ConvertClientVersionToClientVersionBit(ClientVersion client_version);
|
||||
extern ClientVersion ConvertClientVersionBitToClientVersion(uint32 client_version_bit);
|
||||
extern uint32 ConvertClientVersionToExpansion(ClientVersion client_version);
|
||||
|
||||
} /*versions*/
|
||||
|
||||
enum class MobVersion {
|
||||
namespace versions {
|
||||
enum class InventoryVersion {
|
||||
Unknown = 0,
|
||||
Client62,
|
||||
Titanium,
|
||||
@@ -97,29 +99,29 @@ namespace EQEmu
|
||||
OfflineRoF2
|
||||
};
|
||||
|
||||
const MobVersion LastMobVersion = MobVersion::OfflineRoF2;
|
||||
const MobVersion LastPCMobVersion = MobVersion::RoF2;
|
||||
const MobVersion LastNonPCMobVersion = MobVersion::BotPet;
|
||||
const MobVersion LastOfflinePCMobVersion = MobVersion::OfflineRoF2;
|
||||
const size_t MobVersionCount = (static_cast<size_t>(LastMobVersion) + 1);
|
||||
const InventoryVersion LastInventoryVersion = InventoryVersion::OfflineRoF2;
|
||||
const InventoryVersion LastPCInventoryVersion = InventoryVersion::RoF2;
|
||||
const InventoryVersion LastNonPCInventoryVersion = InventoryVersion::BotPet;
|
||||
const InventoryVersion LastOfflinePCInventoryVersion = InventoryVersion::OfflineRoF2;
|
||||
const size_t InventoryVersionCount = (static_cast<size_t>(LastInventoryVersion) + 1);
|
||||
|
||||
bool IsValidMobVersion(MobVersion mob_version);
|
||||
bool IsValidPCMobVersion(MobVersion mob_version);
|
||||
bool IsValidNonPCMobVersion(MobVersion mob_version);
|
||||
bool IsValidOfflinePCMobVersion(MobVersion mob_version);
|
||||
extern bool IsValidInventoryVersion(InventoryVersion inventory_version);
|
||||
extern bool IsValidPCInventoryVersion(InventoryVersion inventory_version);
|
||||
extern bool IsValidNonPCInventoryVersion(InventoryVersion inventory_version);
|
||||
extern bool IsValidOfflinePCInventoryVersion(InventoryVersion inventory_version);
|
||||
|
||||
MobVersion ValidateMobVersion(MobVersion mob_version);
|
||||
MobVersion ValidatePCMobVersion(MobVersion mob_version);
|
||||
MobVersion ValidateNonPCMobVersion(MobVersion mob_version);
|
||||
MobVersion ValidateOfflinePCMobVersion(MobVersion mob_version);
|
||||
extern InventoryVersion ValidateInventoryVersion(InventoryVersion inventory_version);
|
||||
extern InventoryVersion ValidatePCInventoryVersion(InventoryVersion inventory_version);
|
||||
extern InventoryVersion ValidateNonPCInventoryVersion(InventoryVersion inventory_version);
|
||||
extern InventoryVersion ValidateOfflinePCInventoryVersion(InventoryVersion inventory_version);
|
||||
|
||||
const char* MobVersionName(MobVersion mob_version);
|
||||
ClientVersion ConvertMobVersionToClientVersion(MobVersion mob_version);
|
||||
MobVersion ConvertClientVersionToMobVersion(ClientVersion client_version);
|
||||
MobVersion ConvertPCMobVersionToOfflinePCMobVersion(MobVersion mob_version);
|
||||
MobVersion ConvertOfflinePCMobVersionToPCMobVersion(MobVersion mob_version);
|
||||
ClientVersion ConvertOfflinePCMobVersionToClientVersion(MobVersion mob_version);
|
||||
MobVersion ConvertClientVersionToOfflinePCMobVersion(ClientVersion client_version);
|
||||
extern const char* InventoryVersionName(InventoryVersion inventory_version);
|
||||
extern ClientVersion ConvertInventoryVersionToClientVersion(InventoryVersion inventory_version);
|
||||
extern InventoryVersion ConvertClientVersionToInventoryVersion(ClientVersion client_version);
|
||||
extern InventoryVersion ConvertPCInventoryVersionToOfflinePCInventoryVersion(InventoryVersion inventory_version);
|
||||
extern InventoryVersion ConvertOfflinePCInventoryVersionToPCInventoryVersion(InventoryVersion inventory_version);
|
||||
extern ClientVersion ConvertOfflinePCInventoryVersionToClientVersion(InventoryVersion inventory_version);
|
||||
extern InventoryVersion ConvertClientVersionToOfflinePCInventoryVersion(ClientVersion client_version);
|
||||
|
||||
} /*versions*/
|
||||
|
||||
|
||||
@@ -516,6 +516,14 @@ static const uint8 SkillDamageTypes[EQEmu::skills::HIGHEST_SKILL + 1] = // chang
|
||||
*/
|
||||
|
||||
#define INVALID_INDEX -1
|
||||
#define NO_ITEM 0
|
||||
|
||||
// yes..these are redundant... but, they help to identify and define what is actually being performed
|
||||
// plus, since they're pre-op's, they don't affect the actual binary size
|
||||
#define TYPE_BEGIN 0
|
||||
#define SLOT_BEGIN 0
|
||||
#define SUB_INDEX_BEGIN 0
|
||||
#define AUG_INDEX_BEGIN 0
|
||||
|
||||
static const uint32 MAX_SPELL_DB_ID_VAL = 65535;
|
||||
|
||||
|
||||
+189
-791
File diff suppressed because it is too large
Load Diff
+3
-10
@@ -38,13 +38,6 @@ namespace EQEmu
|
||||
class LookupEntry {
|
||||
public:
|
||||
size_t CharacterCreationLimit;
|
||||
int LongBuffs;
|
||||
int ShortBuffs;
|
||||
int DiscBuffs;
|
||||
int TotalBuffs;
|
||||
int NPCBuffs;
|
||||
int PetBuffs;
|
||||
int MercBuffs;
|
||||
};
|
||||
|
||||
const LookupEntry* Lookup(versions::ClientVersion client_version);
|
||||
@@ -54,7 +47,7 @@ namespace EQEmu
|
||||
namespace inventory {
|
||||
class LookupEntry {
|
||||
public:
|
||||
size_t InventoryTypeSize[25]; // should reflect EQEmu::inventory::typeCount referenced in emu_constants.h
|
||||
size_t InventoryTypeSize[legacy::TypeCount];
|
||||
|
||||
uint64 PossessionsBitmask;
|
||||
size_t ItemBagSize;
|
||||
@@ -66,7 +59,7 @@ namespace EQEmu
|
||||
bool AllowOverLevelEquipment;
|
||||
};
|
||||
|
||||
const LookupEntry* Lookup(versions::MobVersion mob_version);
|
||||
const LookupEntry* Lookup(versions::InventoryVersion inventory_version);
|
||||
|
||||
} /*inventory*/
|
||||
|
||||
@@ -76,7 +69,7 @@ namespace EQEmu
|
||||
bool CoinHasWeight;
|
||||
};
|
||||
|
||||
const LookupEntry* Lookup(versions::MobVersion mob_version);
|
||||
const LookupEntry* Lookup(versions::InventoryVersion inventory_version);
|
||||
|
||||
} /*behavior*/
|
||||
|
||||
|
||||
+20
-35
@@ -127,7 +127,7 @@ struct LDoNTrapTemplate
|
||||
|
||||
// All clients translate the character select information to some degree
|
||||
|
||||
struct CharSelectEquip : EQEmu::textures::Texture_Struct, EQEmu::textures::Tint_Struct {};
|
||||
struct CharSelectEquip : EQEmu::Texture_Struct, EQEmu::Tint_Struct {};
|
||||
|
||||
// RoF2-based hybrid struct
|
||||
struct CharacterSelectEntry_Struct
|
||||
@@ -142,7 +142,7 @@ struct CharacterSelectEntry_Struct
|
||||
uint16 Instance;
|
||||
uint8 Gender;
|
||||
uint8 Face;
|
||||
CharSelectEquip Equip[EQEmu::textures::materialCount];
|
||||
CharSelectEquip Equip[EQEmu::textures::TextureCount];
|
||||
uint8 Unknown15; // Seen FF
|
||||
uint8 Unknown19; // Seen FF
|
||||
uint32 DrakkinTattoo;
|
||||
@@ -834,7 +834,7 @@ struct SuspendedMinion_Struct
|
||||
/*002*/ uint32 HP;
|
||||
/*006*/ uint32 Mana;
|
||||
/*010*/ SpellBuff_Struct Buffs[BUFF_COUNT];
|
||||
/*510*/ EQEmu::TextureMaterialProfile Items;
|
||||
/*510*/ EQEmu::TextureShortProfile Items;
|
||||
/*546*/ char Name[64];
|
||||
/*610*/
|
||||
};
|
||||
@@ -942,7 +942,7 @@ struct PlayerProfile_Struct
|
||||
/*0304*/ uint8 ability_time_minutes;
|
||||
/*0305*/ uint8 ability_time_hours; //place holder
|
||||
/*0306*/ uint8 unknown0306[6]; // @bp Spacer/Flag?
|
||||
/*0312*/ EQEmu::TextureMaterialProfile item_material; // Item texture/material of worn/held items
|
||||
/*0312*/ EQEmu::TextureShortProfile item_material; // Item texture/material of worn/held items
|
||||
/*0348*/ uint8 unknown0348[44];
|
||||
/*0392*/ EQEmu::TintProfile item_tint;
|
||||
/*0428*/ AA_Array aa_array[MAX_PP_AA_ARRAY];
|
||||
@@ -1179,7 +1179,7 @@ struct WearChange_Struct{
|
||||
/*010*/ uint32 elite_material; // 1 for Drakkin Elite Material
|
||||
/*014*/ uint32 hero_forge_model; // New to VoA
|
||||
/*018*/ uint32 unknown18; // New to RoF
|
||||
/*022*/ EQEmu::textures::Tint_Struct color;
|
||||
/*022*/ EQEmu::Tint_Struct color;
|
||||
/*026*/ uint8 wear_slot_id;
|
||||
/*027*/
|
||||
};
|
||||
@@ -1643,7 +1643,7 @@ struct LootingItem_Struct {
|
||||
/*002*/ uint32 looter;
|
||||
/*004*/ uint16 slot_id;
|
||||
/*006*/ uint8 unknown3[2];
|
||||
/*008*/ int32 auto_loot;
|
||||
/*008*/ uint32 auto_loot;
|
||||
};
|
||||
|
||||
struct GuildManageStatus_Struct{
|
||||
@@ -1934,7 +1934,8 @@ struct Merchant_Sell_Struct {
|
||||
/*004*/ uint32 playerid; // Player's entity id
|
||||
/*008*/ uint32 itemslot;
|
||||
uint32 unknown12;
|
||||
/*016*/ uint32 quantity;
|
||||
/*016*/ uint8 quantity; // Already sold
|
||||
/*017*/ uint8 Unknown016[3];
|
||||
/*020*/ uint32 price;
|
||||
};
|
||||
struct Merchant_Purchase_Struct {
|
||||
@@ -2071,7 +2072,7 @@ struct AdventureLeaderboard_Struct
|
||||
/*struct Item_Shop_Struct {
|
||||
uint16 merchantid;
|
||||
uint8 itemtype;
|
||||
EQEmu::ItemData item;
|
||||
EQEmu::ItemBase item;
|
||||
uint8 iss_unknown001[6];
|
||||
};*/
|
||||
|
||||
@@ -2508,25 +2509,23 @@ struct BookRequest_Struct {
|
||||
*/
|
||||
struct Object_Struct {
|
||||
/*00*/ uint32 linked_list_addr[2];// They are, get this, prev and next, ala linked list
|
||||
/*08*/ float size; //
|
||||
/*08*/ uint16 size; //
|
||||
/*10*/ uint16 solidtype; //
|
||||
/*12*/ uint32 drop_id; // Unique object id for zone
|
||||
/*16*/ uint16 zone_id; // Redudant, but: Zone the object appears in
|
||||
/*18*/ uint16 zone_instance; //
|
||||
/*20*/ uint32 unknown020; //
|
||||
/*24*/ uint32 unknown024; //
|
||||
/*28*/ float tilt_x;
|
||||
/*32*/ float tilt_y;
|
||||
/*36*/ float heading; // heading
|
||||
/*40*/ float z; // z coord
|
||||
/*44*/ float x; // x coord
|
||||
/*76*/ float y; // y coord
|
||||
/*80*/ char object_name[32]; // Name of object, usually something like IT63_ACTORDEF
|
||||
/*84*/ uint32 unknown076; //
|
||||
/*88*/ uint32 object_type; // Type of object, not directly translated to OP_OpenObject
|
||||
/*92*/ uint32 unknown084; //set to 0xFF
|
||||
uint32 spawn_id; // Spawn Id of client interacting with object
|
||||
|
||||
/*28*/ float heading; // heading
|
||||
/*32*/ float z; // z coord
|
||||
/*36*/ float x; // x coord
|
||||
/*40*/ float y; // y coord
|
||||
/*44*/ char object_name[32]; // Name of object, usually something like IT63_ACTORDEF
|
||||
/*76*/ uint32 unknown076; //
|
||||
/*80*/ uint32 object_type; // Type of object, not directly translated to OP_OpenObject
|
||||
/*84*/ uint32 unknown084; //set to 0xFF
|
||||
/*88*/ uint32 spawn_id; // Spawn Id of client interacting with object
|
||||
/*92*/
|
||||
};
|
||||
// 01 = generic drop, 02 = armor, 19 = weapon
|
||||
//[13:40] and 0xff seems to be indicative of the tradeskill/openable items that end up returning the old style item type in the OP_OpenObject
|
||||
@@ -3517,20 +3516,6 @@ struct RecipeAutoCombine_Struct {
|
||||
// f5 ff ff ff in 'you dont have all the stuff' reply
|
||||
};
|
||||
|
||||
// this is the "value#a" data
|
||||
enum EParticlePoint {
|
||||
eDefault,
|
||||
eChest,
|
||||
eHead,
|
||||
eLeftHand,
|
||||
eRigthHand,
|
||||
eLeftFoot,
|
||||
eRightFood,
|
||||
eLeftEye,
|
||||
eRightEye,
|
||||
eMouth
|
||||
};
|
||||
|
||||
struct LevelAppearance_Struct { //Sends a little graphic on level up
|
||||
uint32 spawn_id;
|
||||
uint32 parm1;
|
||||
|
||||
+30
-2
@@ -29,7 +29,7 @@ EQEmuConfig *EQEmuConfig::_config = nullptr;
|
||||
void EQEmuConfig::do_world(TiXmlElement *ele)
|
||||
{
|
||||
const char *text;
|
||||
TiXmlElement * sub_ele;;
|
||||
TiXmlElement * sub_ele;
|
||||
text = ParseTextBlock(ele, "shortname");
|
||||
if (text) {
|
||||
ShortName = text;
|
||||
@@ -220,6 +220,29 @@ void EQEmuConfig::do_qsdatabase(TiXmlElement *ele)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void EQEmuConfig::do_web_interface(TiXmlElement *ele) {
|
||||
const char *text;
|
||||
|
||||
text = ParseTextBlock(ele, "port", true);
|
||||
if (text)
|
||||
WebInterfacePort = atoi(text);
|
||||
|
||||
text = ParseTextBlock(ele, "cert", true);
|
||||
if (text)
|
||||
WebInterfaceCert = text;
|
||||
|
||||
text = ParseTextBlock(ele, "priv_key", true);
|
||||
if (text)
|
||||
WebInterfacePrivKey = text;
|
||||
|
||||
TiXmlElement *sub_ele = ele->FirstChildElement("ssl");
|
||||
if (sub_ele != nullptr) {
|
||||
WebInterfaceUseSSL = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void EQEmuConfig::do_zones(TiXmlElement *ele)
|
||||
{
|
||||
const char *text;
|
||||
@@ -486,6 +509,8 @@ std::string EQEmuConfig::GetByName(const std::string &var_name) const
|
||||
return ("");
|
||||
}
|
||||
|
||||
|
||||
|
||||
void EQEmuConfig::Dump() const
|
||||
{
|
||||
std::cout << "ShortName = " << ShortName << std::endl;
|
||||
@@ -516,6 +541,10 @@ void EQEmuConfig::Dump() const
|
||||
std::cout << "QSDatabasePassword = " << QSDatabasePassword << std::endl;
|
||||
std::cout << "QSDatabaseDB = " << QSDatabaseDB << std::endl;
|
||||
std::cout << "QSDatabasePort = " << QSDatabasePort << std::endl;
|
||||
std::cout << "WebInterfacePort = " << WebInterfacePort << std::endl;
|
||||
std::cout << "WebInterfaceUseSSL = " << WebInterfaceUseSSL << std::endl;
|
||||
std::cout << "WebInterfaceCert = " << WebInterfaceCert << std::endl;
|
||||
std::cout << "WebInterfacePrivKey = " << WebInterfacePrivKey << std::endl;
|
||||
std::cout << "SpellsFile = " << SpellsFile << std::endl;
|
||||
std::cout << "OpCodesFile = " << OpCodesFile << std::endl;
|
||||
std::cout << "PluginPlFile = " << PluginPlFile << std::endl;
|
||||
@@ -529,6 +558,5 @@ void EQEmuConfig::Dump() const
|
||||
std::cout << "ZonePortLow = " << ZonePortLow << std::endl;
|
||||
std::cout << "ZonePortHigh = " << ZonePortHigh << std::endl;
|
||||
std::cout << "DefaultStatus = " << (int)DefaultStatus << std::endl;
|
||||
// std::cout << "DynamicCount = " << DynamicCount << std::endl;
|
||||
}
|
||||
|
||||
|
||||
@@ -76,6 +76,12 @@ class EQEmuConfig : public XMLParser
|
||||
std::string QSDatabaseDB;
|
||||
uint16 QSDatabasePort;
|
||||
|
||||
// from <web_interface>
|
||||
uint16 WebInterfacePort;
|
||||
bool WebInterfaceUseSSL;
|
||||
std::string WebInterfaceCert;
|
||||
std::string WebInterfacePrivKey;
|
||||
|
||||
// From <files/>
|
||||
std::string SpellsFile;
|
||||
std::string OpCodesFile;
|
||||
@@ -220,7 +226,7 @@ class EQEmuConfig : public XMLParser
|
||||
return _config->ParseFile(EQEmuConfig::ConfigFile.c_str(), "server");
|
||||
}
|
||||
|
||||
void Dump() const;
|
||||
void Dump() const;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -4,6 +4,7 @@ ELEMENT(mailserver)
|
||||
ELEMENT(zones)
|
||||
ELEMENT(database)
|
||||
ELEMENT(qsdatabase)
|
||||
ELEMENT(web_interface)
|
||||
ELEMENT(files)
|
||||
ELEMENT(directories)
|
||||
ELEMENT(launcher)
|
||||
|
||||
@@ -83,7 +83,6 @@ namespace Logs {
|
||||
Server_Client_Packet_With_Dump,
|
||||
Client_Server_Packet_With_Dump,
|
||||
Login_Server,
|
||||
Client_Login,
|
||||
MaxCategoryID /* Don't Remove this*/
|
||||
};
|
||||
|
||||
@@ -132,8 +131,7 @@ namespace Logs {
|
||||
"Packet :: Client -> Server Unhandled",
|
||||
"Packet :: Server -> Client (Dump)",
|
||||
"Packet :: Client -> Server (Dump)",
|
||||
"Login Server",
|
||||
"Client Login"
|
||||
"Login Server"
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
+2
-2
@@ -19,7 +19,7 @@
|
||||
#define EXTENDED_PROFILE_H
|
||||
|
||||
#include "eq_packet_structs.h"
|
||||
#include "inventory_profile.h"
|
||||
#include "item.h"
|
||||
|
||||
#pragma pack(1)
|
||||
|
||||
@@ -40,7 +40,7 @@ struct ExtendedProfile_Struct {
|
||||
uint16 old_pet_hp; /* Not Used */
|
||||
uint16 old_pet_mana; /* Not Used */
|
||||
SpellBuff_Struct pet_buffs[BUFF_COUNT]; /* Not Used */
|
||||
EQEmu::TextureMaterialProfile pet_items; /* Not Used */
|
||||
EQEmu::TextureShortProfile pet_items; /* Not Used */
|
||||
char merc_name[64]; /* Used */
|
||||
|
||||
uint32 aa_effects; /* Used */
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,230 +0,0 @@
|
||||
/* EQEMu: Everquest Server Emulator
|
||||
|
||||
Copyright (C) 2001-2016 EQEMu Development Team (http://eqemulator.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; version 2 of the License.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY except by those people which sell it, which
|
||||
are required to give you total support for your newly bought product;
|
||||
without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 04111-1307 USA
|
||||
*/
|
||||
|
||||
// @merth notes:
|
||||
// These classes could be optimized with database reads/writes by storing
|
||||
// a status flag indicating how object needs to interact with database
|
||||
|
||||
#ifndef COMMON_INVENTORY_PROFILE_H
|
||||
#define COMMON_INVENTORY_PROFILE_H
|
||||
|
||||
|
||||
#include "item_instance.h"
|
||||
|
||||
#include <list>
|
||||
|
||||
|
||||
//FatherNitwit: location bits for searching specific
|
||||
//places with HasItem() and HasItemByUse()
|
||||
enum {
|
||||
invWhereWorn = 0x01,
|
||||
invWherePersonal = 0x02, //in the character's inventory
|
||||
invWhereBank = 0x04,
|
||||
invWhereSharedBank = 0x08,
|
||||
invWhereTrading = 0x10,
|
||||
invWhereCursor = 0x20
|
||||
};
|
||||
|
||||
// ########################################
|
||||
// Class: Queue
|
||||
// Queue that allows a read-only iterator
|
||||
class ItemInstQueue
|
||||
{
|
||||
public:
|
||||
~ItemInstQueue();
|
||||
/////////////////////////
|
||||
// Public Methods
|
||||
/////////////////////////
|
||||
|
||||
inline std::list<EQEmu::ItemInstance*>::const_iterator cbegin() { return m_list.cbegin(); }
|
||||
inline std::list<EQEmu::ItemInstance*>::const_iterator cend() { return m_list.cend(); }
|
||||
|
||||
inline int size() { return static_cast<int>(m_list.size()); } // TODO: change to size_t
|
||||
inline bool empty() { return m_list.empty(); }
|
||||
|
||||
void push(EQEmu::ItemInstance* inst);
|
||||
void push_front(EQEmu::ItemInstance* inst);
|
||||
EQEmu::ItemInstance* pop();
|
||||
EQEmu::ItemInstance* pop_back();
|
||||
EQEmu::ItemInstance* peek_front() const;
|
||||
|
||||
protected:
|
||||
/////////////////////////
|
||||
// Protected Members
|
||||
/////////////////////////
|
||||
|
||||
std::list<EQEmu::ItemInstance*> m_list;
|
||||
};
|
||||
|
||||
// ########################################
|
||||
// Class: EQEmu::InventoryProfile
|
||||
// Character inventory
|
||||
namespace EQEmu
|
||||
{
|
||||
class InventoryProfile
|
||||
{
|
||||
friend class ItemInstance;
|
||||
public:
|
||||
///////////////////////////////
|
||||
// Public Methods
|
||||
///////////////////////////////
|
||||
|
||||
InventoryProfile() { m_mob_version = versions::MobVersion::Unknown; m_mob_version_set = false; }
|
||||
~InventoryProfile();
|
||||
|
||||
bool SetInventoryVersion(versions::MobVersion inventory_version) {
|
||||
if (!m_mob_version_set) {
|
||||
m_mob_version = versions::ValidateMobVersion(inventory_version);
|
||||
return (m_mob_version_set = true);
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
bool SetInventoryVersion(versions::ClientVersion client_version) { return SetInventoryVersion(versions::ConvertClientVersionToMobVersion(client_version)); }
|
||||
|
||||
versions::MobVersion InventoryVersion() { return m_mob_version; }
|
||||
|
||||
static void CleanDirty();
|
||||
static void MarkDirty(ItemInstance *inst);
|
||||
|
||||
// Retrieve a writeable item at specified slot
|
||||
ItemInstance* GetItem(int16 slot_id) const;
|
||||
ItemInstance* GetItem(int16 slot_id, uint8 bagidx) const;
|
||||
|
||||
inline std::list<ItemInstance*>::const_iterator cursor_cbegin() { return m_cursor.cbegin(); }
|
||||
inline std::list<ItemInstance*>::const_iterator cursor_cend() { return m_cursor.cend(); }
|
||||
|
||||
inline int CursorSize() { return m_cursor.size(); }
|
||||
inline bool CursorEmpty() { return m_cursor.empty(); }
|
||||
|
||||
// Retrieve a read-only item from inventory
|
||||
inline const ItemInstance* operator[](int16 slot_id) const { return GetItem(slot_id); }
|
||||
|
||||
// Add item to inventory
|
||||
int16 PutItem(int16 slot_id, const ItemInstance& inst);
|
||||
|
||||
// Add item to cursor queue
|
||||
int16 PushCursor(const ItemInstance& inst);
|
||||
|
||||
// Get cursor item in front of queue
|
||||
ItemInstance* GetCursorItem();
|
||||
|
||||
// Swap items in inventory
|
||||
bool SwapItem(int16 slot_a, int16 slot_b);
|
||||
|
||||
// Remove item from inventory
|
||||
bool DeleteItem(int16 slot_id, uint8 quantity = 0);
|
||||
|
||||
// Checks All items in a bag for No Drop
|
||||
bool CheckNoDrop(int16 slot_id, bool recurse = true);
|
||||
|
||||
// Remove item from inventory (and take control of memory)
|
||||
ItemInstance* PopItem(int16 slot_id);
|
||||
|
||||
// Check whether there is space for the specified number of the specified item.
|
||||
bool HasSpaceForItem(const ItemData *ItemToTry, int16 Quantity);
|
||||
|
||||
// Check whether item exists in inventory
|
||||
// where argument specifies OR'd list of invWhere constants to look
|
||||
int16 HasItem(uint32 item_id, uint8 quantity = 0, uint8 where = 0xFF);
|
||||
|
||||
// Check whether item exists in inventory
|
||||
// where argument specifies OR'd list of invWhere constants to look
|
||||
int16 HasItemByUse(uint8 use, uint8 quantity = 0, uint8 where = 0xFF);
|
||||
|
||||
// Check whether item exists in inventory
|
||||
// where argument specifies OR'd list of invWhere constants to look
|
||||
int16 HasItemByLoreGroup(uint32 loregroup, uint8 where = 0xFF);
|
||||
|
||||
// Locate an available inventory slot
|
||||
int16 FindFreeSlot(bool for_bag, bool try_cursor, uint8 min_size = 0, bool is_arrow = false);
|
||||
int16 FindFreeSlotForTradeItem(const ItemInstance* inst);
|
||||
|
||||
// Calculate slot_id for an item within a bag
|
||||
static int16 CalcSlotId(int16 slot_id); // Calc parent bag's slot_id
|
||||
static int16 CalcSlotId(int16 bagslot_id, uint8 bagidx); // Calc slot_id for item inside bag
|
||||
static uint8 CalcBagIdx(int16 slot_id); // Calc bagidx for slot_id
|
||||
static int16 CalcSlotFromMaterial(uint8 material);
|
||||
static uint8 CalcMaterialFromSlot(int16 equipslot);
|
||||
|
||||
static bool CanItemFitInContainer(const ItemData *ItemToTry, const ItemData *Container);
|
||||
|
||||
// Test for valid inventory casting slot
|
||||
bool SupportsClickCasting(int16 slot_id);
|
||||
bool SupportsPotionBeltCasting(int16 slot_id);
|
||||
|
||||
// Test whether a given slot can support a container item
|
||||
static bool SupportsContainers(int16 slot_id);
|
||||
|
||||
int GetSlotByItemInst(ItemInstance *inst);
|
||||
|
||||
uint8 FindBrightestLightType();
|
||||
|
||||
void dumpEntireInventory();
|
||||
void dumpWornItems();
|
||||
void dumpInventory();
|
||||
void dumpBankItems();
|
||||
void dumpSharedBankItems();
|
||||
|
||||
void SetCustomItemData(uint32 character_id, int16 slot_id, std::string identifier, std::string value);
|
||||
void SetCustomItemData(uint32 character_id, int16 slot_id, std::string identifier, int value);
|
||||
void SetCustomItemData(uint32 character_id, int16 slot_id, std::string identifier, float value);
|
||||
void SetCustomItemData(uint32 character_id, int16 slot_id, std::string identifier, bool value);
|
||||
std::string GetCustomItemData(int16 slot_id, std::string identifier);
|
||||
protected:
|
||||
///////////////////////////////
|
||||
// Protected Methods
|
||||
///////////////////////////////
|
||||
|
||||
int GetSlotByItemInstCollection(const std::map<int16, ItemInstance*> &collection, ItemInstance *inst);
|
||||
void dumpItemCollection(const std::map<int16, ItemInstance*> &collection);
|
||||
void dumpBagContents(ItemInstance *inst, std::map<int16, ItemInstance*>::const_iterator *it);
|
||||
|
||||
// Retrieves item within an inventory bucket
|
||||
ItemInstance* _GetItem(const std::map<int16, ItemInstance*>& bucket, int16 slot_id) const;
|
||||
|
||||
// Private "put" item into bucket, without regard for what is currently in bucket
|
||||
int16 _PutItem(int16 slot_id, ItemInstance* inst);
|
||||
|
||||
// Checks an inventory bucket for a particular item
|
||||
int16 _HasItem(std::map<int16, ItemInstance*>& bucket, uint32 item_id, uint8 quantity);
|
||||
int16 _HasItem(ItemInstQueue& iqueue, uint32 item_id, uint8 quantity);
|
||||
int16 _HasItemByUse(std::map<int16, ItemInstance*>& bucket, uint8 use, uint8 quantity);
|
||||
int16 _HasItemByUse(ItemInstQueue& iqueue, uint8 use, uint8 quantity);
|
||||
int16 _HasItemByLoreGroup(std::map<int16, ItemInstance*>& bucket, uint32 loregroup);
|
||||
int16 _HasItemByLoreGroup(ItemInstQueue& iqueue, uint32 loregroup);
|
||||
|
||||
|
||||
// Player inventory
|
||||
std::map<int16, ItemInstance*> m_worn; // Items worn by character
|
||||
std::map<int16, ItemInstance*> m_inv; // Items in character personal inventory
|
||||
std::map<int16, ItemInstance*> m_bank; // Items in character bank
|
||||
std::map<int16, ItemInstance*> m_shbank; // Items in character shared bank
|
||||
std::map<int16, ItemInstance*> m_trade; // Items in a trade session
|
||||
::ItemInstQueue m_cursor; // Items on cursor: FIFO
|
||||
|
||||
private:
|
||||
// Active mob version
|
||||
versions::MobVersion m_mob_version;
|
||||
bool m_mob_version_set;
|
||||
};
|
||||
}
|
||||
|
||||
#endif /*COMMON_INVENTORY_PROFILE_H*/
|
||||
@@ -1,397 +0,0 @@
|
||||
/* EQEMu: Everquest Server Emulator
|
||||
|
||||
Copyright (C) 2001-2016 EQEMu Development Team (http://eqemulator.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; version 2 of the License.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY except by those people which sell it, which
|
||||
are required to give you total support for your newly bought product;
|
||||
without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public 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 "inventory_slot.h"
|
||||
#include "textures.h"
|
||||
#include "string_util.h"
|
||||
|
||||
|
||||
int8 EQEmu::inventory::ConvertEquipmentIndexToTextureIndex(int16 slot_index)
|
||||
{
|
||||
switch (slot_index) {
|
||||
case slotHead:
|
||||
return textures::armorHead;
|
||||
case slotChest:
|
||||
return textures::armorChest;
|
||||
case slotArms:
|
||||
return textures::armorArms;
|
||||
case slotWrist1:
|
||||
return textures::armorWrist;
|
||||
case slotHands:
|
||||
return textures::armorHands;
|
||||
case slotLegs:
|
||||
return textures::armorLegs;
|
||||
case slotFeet:
|
||||
return textures::armorFeet;
|
||||
case slotPrimary:
|
||||
return textures::weaponPrimary;
|
||||
case slotSecondary:
|
||||
return textures::weaponSecondary;
|
||||
default:
|
||||
return textures::textureInvalid;
|
||||
}
|
||||
}
|
||||
|
||||
int8 EQEmu::inventory::ConvertEquipmentSlotToTextureIndex(const InventorySlot& inventory_slot)
|
||||
{
|
||||
if ((!inventory_slot.Typeless() && !inventory_slot.IsTypeIndex(typePossessions)) || !inventory_slot.IsContainerIndex(containerInvalid) || !inventory_slot.IsSocketIndex(socketInvalid))
|
||||
return textures::textureInvalid;
|
||||
|
||||
return ConvertEquipmentIndexToTextureIndex(inventory_slot.SlotIndex());
|
||||
}
|
||||
|
||||
int16 EQEmu::inventory::ConvertTextureIndexToEquipmentIndex(int8 texture_index)
|
||||
{
|
||||
switch (texture_index) {
|
||||
case textures::armorHead:
|
||||
return slotHead;
|
||||
case textures::armorChest:
|
||||
return slotChest;
|
||||
case textures::armorArms:
|
||||
return slotArms;
|
||||
case textures::armorWrist:
|
||||
return slotWrist1;
|
||||
case textures::armorHands:
|
||||
return slotHands;
|
||||
case textures::armorLegs:
|
||||
return slotLegs;
|
||||
case textures::armorFeet:
|
||||
return slotFeet;
|
||||
case textures::weaponPrimary:
|
||||
return slotPrimary;
|
||||
case textures::weaponSecondary:
|
||||
return slotSecondary;
|
||||
default:
|
||||
return slotInvalid;
|
||||
}
|
||||
}
|
||||
|
||||
bool EQEmu::InventorySlot::IsValidSlot() const
|
||||
{
|
||||
if (_typeless)
|
||||
return false;
|
||||
|
||||
int16 slot_count = inventory::SlotCount(_type_index);
|
||||
if (!slot_count || _slot_index < inventory::slotBegin || _slot_index >= slot_count)
|
||||
return false;
|
||||
|
||||
if (_container_index < inventory::containerInvalid || _container_index >= inventory::ContainerCount)
|
||||
return false;
|
||||
|
||||
if (_socket_index < inventory::socketInvalid || _socket_index >= inventory::SocketCount)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool EQEmu::InventorySlot::IsDeleteSlot() const
|
||||
{
|
||||
if (_typeless)
|
||||
return (_slot_index == inventory::slotInvalid && _container_index == inventory::containerInvalid && _socket_index == inventory::socketInvalid);
|
||||
else
|
||||
return (_type_index == inventory::typeInvalid && _slot_index == inventory::slotInvalid && _container_index == inventory::containerInvalid && _socket_index == inventory::socketInvalid);
|
||||
}
|
||||
|
||||
bool EQEmu::InventorySlot::IsEquipmentIndex(int16 slot_index)
|
||||
{
|
||||
/*if (slot_index < inventory::EquipmentBegin || slot_index > inventory::EquipmentEnd)
|
||||
return false;*/
|
||||
if ((slot_index < legacy::EQUIPMENT_BEGIN || slot_index > legacy::EQUIPMENT_END) && slot_index != legacy::SLOT_POWER_SOURCE)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool EQEmu::InventorySlot::IsGeneralIndex(int16 slot_index)
|
||||
{
|
||||
/*if (slot_index < inventory::GeneralBegin || slot_index > inventory::GeneralEnd)
|
||||
return false;*/
|
||||
if (slot_index < legacy::GENERAL_BEGIN || slot_index > legacy::GENERAL_END)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool EQEmu::InventorySlot::IsCursorIndex(int16 slot_index)
|
||||
{
|
||||
/*if (slot_index != inventory::slotCursor)
|
||||
return false;*/
|
||||
if (slot_index != legacy::SLOT_CURSOR)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool EQEmu::InventorySlot::IsWeaponIndex(int16 slot_index)
|
||||
{
|
||||
/*if ((slot_index != inventory::slotRange) && (slot_index != inventory::slotPrimary) && (slot_index != inventory::slotSecondary))
|
||||
return false;*/
|
||||
if ((slot_index != legacy::SLOT_RANGE) && (slot_index != legacy::SLOT_PRIMARY) && (slot_index != legacy::SLOT_SECONDARY))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool EQEmu::InventorySlot::IsTextureIndex(int16 slot_index)
|
||||
{
|
||||
switch (slot_index) {
|
||||
case inventory::slotHead:
|
||||
case inventory::slotChest:
|
||||
case inventory::slotArms:
|
||||
case inventory::slotWrist1:
|
||||
case inventory::slotHands:
|
||||
case inventory::slotLegs:
|
||||
case inventory::slotFeet:
|
||||
case inventory::slotPrimary:
|
||||
case inventory::slotSecondary:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool EQEmu::InventorySlot::IsTintableIndex(int16 slot_index)
|
||||
{
|
||||
switch (slot_index) {
|
||||
case inventory::slotHead:
|
||||
case inventory::slotChest:
|
||||
case inventory::slotArms:
|
||||
case inventory::slotWrist1:
|
||||
case inventory::slotHands:
|
||||
case inventory::slotLegs:
|
||||
case inventory::slotFeet:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool EQEmu::InventorySlot::IsEquipmentSlot() const
|
||||
{
|
||||
if (!_typeless && (_type_index != inventory::typePossessions))
|
||||
return false;
|
||||
|
||||
if ((_container_index != inventory::containerInvalid) || (_socket_index != inventory::socketInvalid))
|
||||
return false;
|
||||
|
||||
return IsEquipmentIndex(_slot_index);
|
||||
}
|
||||
|
||||
bool EQEmu::InventorySlot::IsGeneralSlot() const
|
||||
{
|
||||
if (!_typeless && (_type_index != inventory::typePossessions))
|
||||
return false;
|
||||
|
||||
if ((_container_index != inventory::containerInvalid) || (_socket_index != inventory::socketInvalid))
|
||||
return false;
|
||||
|
||||
return IsGeneralIndex(_socket_index);
|
||||
}
|
||||
|
||||
bool EQEmu::InventorySlot::IsCursorSlot() const
|
||||
{
|
||||
if (!_typeless && (_type_index != inventory::typePossessions))
|
||||
return false;
|
||||
|
||||
if ((_container_index != inventory::containerInvalid) || (_socket_index != inventory::socketInvalid))
|
||||
return false;
|
||||
|
||||
return IsCursorIndex(_slot_index);
|
||||
}
|
||||
|
||||
bool EQEmu::InventorySlot::IsWeaponSlot() const
|
||||
{
|
||||
if (!_typeless && (_type_index != inventory::typePossessions))
|
||||
return false;
|
||||
|
||||
if ((_container_index != inventory::containerInvalid) || (_socket_index != inventory::socketInvalid))
|
||||
return false;
|
||||
|
||||
return IsWeaponIndex(_slot_index);
|
||||
}
|
||||
|
||||
bool EQEmu::InventorySlot::IsTextureSlot() const
|
||||
{
|
||||
if (!_typeless && (_type_index != inventory::typePossessions))
|
||||
return false;
|
||||
|
||||
if ((_container_index != inventory::containerInvalid) || (_socket_index != inventory::socketInvalid))
|
||||
return false;
|
||||
|
||||
return IsTextureIndex(_slot_index);
|
||||
}
|
||||
|
||||
bool EQEmu::InventorySlot::IsTintableSlot() const
|
||||
{
|
||||
if (!_typeless && (_type_index != inventory::typePossessions))
|
||||
return false;
|
||||
|
||||
if ((_container_index != inventory::containerInvalid) || (_socket_index != inventory::socketInvalid))
|
||||
return false;
|
||||
|
||||
return IsTintableIndex(_slot_index);
|
||||
}
|
||||
|
||||
bool EQEmu::InventorySlot::IsSlot() const
|
||||
{
|
||||
if (!_typeless && (_type_index == inventory::typeInvalid))
|
||||
return false;
|
||||
if (_slot_index == inventory::slotInvalid)
|
||||
return false;
|
||||
if (_container_index != inventory::containerInvalid)
|
||||
return false;
|
||||
if (_socket_index != inventory::socketInvalid)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool EQEmu::InventorySlot::IsSlotSocket() const
|
||||
{
|
||||
if (!_typeless && (_type_index == inventory::typeInvalid))
|
||||
return false;
|
||||
if (_slot_index == inventory::slotInvalid)
|
||||
return false;
|
||||
if (_container_index != inventory::containerInvalid)
|
||||
return false;
|
||||
if (_socket_index == inventory::socketInvalid)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool EQEmu::InventorySlot::IsContainer() const
|
||||
{
|
||||
if (!_typeless && (_type_index == inventory::typeInvalid))
|
||||
return false;
|
||||
if (_slot_index == inventory::slotInvalid)
|
||||
return false;
|
||||
if (_container_index == inventory::containerInvalid)
|
||||
return false;
|
||||
if (_socket_index != inventory::socketInvalid)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool EQEmu::InventorySlot::IsContainerSocket() const
|
||||
{
|
||||
if (!_typeless && (_type_index == inventory::typeInvalid))
|
||||
return false;
|
||||
if (_slot_index == inventory::slotInvalid)
|
||||
return false;
|
||||
if (_container_index == inventory::containerInvalid)
|
||||
return false;
|
||||
if (_socket_index == inventory::socketInvalid)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
EQEmu::InventorySlot EQEmu::InventorySlot::ToTopOwner() const
|
||||
{
|
||||
return InventorySlot(_type_index, _slot_index);
|
||||
}
|
||||
|
||||
EQEmu::InventorySlot EQEmu::InventorySlot::ToOwner() const
|
||||
{
|
||||
if (IsSlot() || IsSlotSocket() || IsContainer())
|
||||
return InventorySlot(_type_index, _slot_index);
|
||||
|
||||
if (IsContainerSocket())
|
||||
return InventorySlot(_type_index, _slot_index, _container_index);
|
||||
|
||||
return InventorySlot();
|
||||
}
|
||||
|
||||
const std::string EQEmu::InventorySlot::ToString() const
|
||||
{
|
||||
return StringFormat("(%i%s, %i, %i, %i)", _type_index, (_typeless ? " [typeless]" : ""), _slot_index, _container_index, _socket_index);
|
||||
}
|
||||
|
||||
const std::string EQEmu::InventorySlot::ToName() const
|
||||
{
|
||||
return StringFormat("InventorySlot - _type_index: %i%s, _slot_index: %i, _container_index: %i, _socket_index: %i", _type_index, (_typeless ? " [typeless]" : ""), _slot_index, _container_index, _socket_index);
|
||||
}
|
||||
|
||||
void EQEmu::InventorySlot::SetInvalidSlot()
|
||||
{
|
||||
_type_index = inventory::typeInvalid;
|
||||
_slot_index = inventory::slotInvalid;
|
||||
_container_index = inventory::containerInvalid;
|
||||
_socket_index = inventory::socketInvalid;
|
||||
}
|
||||
|
||||
//bool EQEmu::InventorySlot::IsBonusIndex(int16 slot_index)
|
||||
//{
|
||||
// if ((slot_index >= inventory::EquipmentBegin) && (slot_index <= inventory::EquipmentEnd) && (slot_index != inventory::slotAmmo))
|
||||
// return true;
|
||||
//
|
||||
// return false;
|
||||
//}
|
||||
|
||||
//bool EQEmu::InventorySlot::IsBonusSlot() const
|
||||
//{
|
||||
// if ((_type_index != inventory::typePossessions) || (_container_index != inventory::containerInvalid) || (_socket_index != inventory::socketInvalid))
|
||||
// return false;
|
||||
//
|
||||
// return IsBonusIndex(_slot_index);
|
||||
//}
|
||||
|
||||
bool inventory_slot_typeless_lessthan(const EQEmu::InventorySlot& lhs, const EQEmu::InventorySlot& rhs)
|
||||
{
|
||||
if (lhs.SlotIndex() < rhs.SlotIndex())
|
||||
return true;
|
||||
|
||||
if ((lhs.SlotIndex() == rhs.SlotIndex()) && (lhs.ContainerIndex() < rhs.ContainerIndex()))
|
||||
return true;
|
||||
|
||||
if ((lhs.SlotIndex() == rhs.SlotIndex()) && (lhs.ContainerIndex() == rhs.ContainerIndex()) && (lhs.SocketIndex() < rhs.SocketIndex()))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool EQEmu::InventorySlot::operator<(const InventorySlot& rhs) const
|
||||
{
|
||||
if (Typeless() || rhs.Typeless())
|
||||
return inventory_slot_typeless_lessthan(*this, rhs);
|
||||
|
||||
if (TypeIndex() < rhs.TypeIndex())
|
||||
return true;
|
||||
|
||||
if ((TypeIndex() == rhs.TypeIndex()) && (SlotIndex() < rhs.SlotIndex()))
|
||||
return true;
|
||||
|
||||
if ((TypeIndex() == rhs.TypeIndex()) && (SlotIndex() == rhs.SlotIndex()) && (ContainerIndex() < rhs.ContainerIndex()))
|
||||
return true;
|
||||
|
||||
if ((TypeIndex() == rhs.TypeIndex()) && (SlotIndex() == rhs.SlotIndex()) && (ContainerIndex() == rhs.ContainerIndex()) && (SocketIndex() < rhs.SocketIndex()))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool EQEmu::operator==(const InventorySlot& lhs, const InventorySlot& rhs)
|
||||
{
|
||||
if (lhs.Typeless() || rhs.Typeless())
|
||||
return ((lhs.SlotIndex() == rhs.SlotIndex()) && (lhs.ContainerIndex() == rhs.ContainerIndex()) && (lhs.SocketIndex() == rhs.SocketIndex()));
|
||||
|
||||
return ((lhs.TypeIndex() == rhs.TypeIndex()) && (lhs.SlotIndex() == rhs.SlotIndex()) && (lhs.ContainerIndex() == rhs.ContainerIndex()) && (lhs.SocketIndex() == rhs.SocketIndex()));
|
||||
}
|
||||
@@ -1,133 +0,0 @@
|
||||
/* EQEMu: Everquest Server Emulator
|
||||
|
||||
Copyright (C) 2001-2016 EQEMu Development Team (http://eqemulator.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; version 2 of the License.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY except by those people which sell it, which
|
||||
are required to give you total support for your newly bought product;
|
||||
without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public 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 COMMON_INVENTORY_SLOT
|
||||
#define COMMON_INVENTORY_SLOT
|
||||
|
||||
#include "emu_constants.h"
|
||||
|
||||
|
||||
namespace EQEmu
|
||||
{
|
||||
class InventorySlot;
|
||||
|
||||
namespace inventory {
|
||||
int8 ConvertEquipmentIndexToTextureIndex(int16 slot_index);
|
||||
int8 ConvertEquipmentSlotToTextureIndex(const InventorySlot& inventory_slot);
|
||||
int16 ConvertTextureIndexToEquipmentIndex(int8 texture_index);
|
||||
}
|
||||
|
||||
class InventorySlot {
|
||||
public:
|
||||
InventorySlot() : _type_index(inventory::typeInvalid), _slot_index(inventory::slotInvalid), _container_index(inventory::containerInvalid), _socket_index(inventory::socketInvalid), _typeless(false) { }
|
||||
InventorySlot(int16 type_index) : _type_index(type_index), _slot_index(inventory::slotInvalid), _container_index(inventory::containerInvalid), _socket_index(inventory::socketInvalid), _typeless(false) { }
|
||||
InventorySlot(int16 type_index, int16 parent_index) : _type_index(type_index), _slot_index(parent_index), _container_index(inventory::containerInvalid), _socket_index(inventory::socketInvalid), _typeless(false) { }
|
||||
InventorySlot(int16 type_index, int16 parent_index, int16 bag_index) : _type_index(type_index), _slot_index(parent_index), _container_index(bag_index), _socket_index(inventory::socketInvalid), _typeless(false) { }
|
||||
InventorySlot(int16 type_index, int16 parent_index, int16 bag_index, int16 aug_index) : _type_index(type_index), _slot_index(parent_index), _container_index(bag_index), _socket_index(aug_index), _typeless(false) { }
|
||||
InventorySlot(const InventorySlot& r) : _type_index(r._type_index), _slot_index(r._slot_index), _container_index(r._container_index), _socket_index(r._socket_index), _typeless(r._typeless) { }
|
||||
InventorySlot(int16 type_index, const InventorySlot& r) : _type_index(type_index), _slot_index(r._slot_index), _container_index(r._container_index), _socket_index(r._socket_index), _typeless(false) { }
|
||||
|
||||
inline int16 TypeIndex() const { return _type_index; }
|
||||
inline int16 SlotIndex() const { return _slot_index; }
|
||||
inline int16 ContainerIndex() const { return _container_index; }
|
||||
inline int16 SocketIndex() const { return _socket_index; }
|
||||
|
||||
bool Typeless() const { return _typeless; }
|
||||
|
||||
bool IsValidSlot() const;
|
||||
bool IsDeleteSlot() const;
|
||||
|
||||
static bool IsEquipmentIndex(int16 slot_index);
|
||||
static bool IsGeneralIndex(int16 slot_index);
|
||||
static bool IsCursorIndex(int16 slot_index);
|
||||
static bool IsWeaponIndex(int16 slot_index);
|
||||
static bool IsTextureIndex(int16 slot_index);
|
||||
static bool IsTintableIndex(int16 slot_index);
|
||||
|
||||
bool IsEquipmentSlot() const;
|
||||
bool IsGeneralSlot() const;
|
||||
bool IsCursorSlot() const;
|
||||
bool IsWeaponSlot() const;
|
||||
bool IsTextureSlot() const;
|
||||
bool IsTintableSlot() const;
|
||||
|
||||
bool IsSlot() const;
|
||||
bool IsSlotSocket() const;
|
||||
bool IsContainer() const;
|
||||
bool IsContainerSocket() const;
|
||||
|
||||
InventorySlot ToTopOwner() const;
|
||||
InventorySlot ToOwner() const;
|
||||
|
||||
const std::string ToString() const;
|
||||
const std::string ToName() const;
|
||||
|
||||
bool IsTypeIndex(int16 type_index) const { return (_type_index == type_index); }
|
||||
bool IsSlotIndex(int16 slot_index) const { return (_slot_index == slot_index); }
|
||||
bool IsContainerIndex(int16 container_index) const { return (_container_index == container_index); }
|
||||
bool IsSocketIndex(int16 socket_index) const { return (_socket_index == socket_index); }
|
||||
|
||||
void SetType(int16 type_index) { _type_index = type_index; }
|
||||
void SetSlot(int16 slot_index) { _slot_index = slot_index; }
|
||||
void SetContainer(int16 container_index) { _container_index = container_index; }
|
||||
void SetSocket(int16 socket_index) { _socket_index = socket_index; }
|
||||
|
||||
void SetInvalidSlot();
|
||||
|
||||
void SetTypeInvalid() { _type_index = inventory::typeInvalid; }
|
||||
void SetSlotInvalid() { _slot_index = inventory::slotInvalid; }
|
||||
void SetContainerInvalid() { _container_index = inventory::containerInvalid; }
|
||||
void SetSocketInvalid() { _socket_index = inventory::socketInvalid; }
|
||||
|
||||
void SetTypeBegin() { _type_index = inventory::typeBegin; }
|
||||
void SetSlotBegin() { _slot_index = inventory::slotBegin; }
|
||||
void SetContainerBegin() { _container_index = inventory::containerBegin; }
|
||||
void SetSocketBegin() { _socket_index = inventory::socketBegin; }
|
||||
|
||||
void IncrementType() { ++_type_index; }
|
||||
void IncrementSlot() { ++_slot_index; }
|
||||
void IncrementContainer() { ++_container_index; }
|
||||
void IncrementSocket() { ++_socket_index; }
|
||||
|
||||
void SetTypeless() { _typeless = true; }
|
||||
void ClearTypeless() { _typeless = false; }
|
||||
|
||||
// these two methods should really check for all bonus-valid slots..currently checks for equipment only (rework needed)
|
||||
//static bool IsBonusIndex(int16 slot_index);
|
||||
//bool IsBonusSlot() const;
|
||||
|
||||
bool operator<(const InventorySlot& rhs) const;
|
||||
|
||||
private:
|
||||
int16 _type_index;
|
||||
//int16 _unknown2; // not implemented
|
||||
int16 _slot_index;
|
||||
int16 _container_index;
|
||||
int16 _socket_index;
|
||||
//int16 _unknown1; // not implemented
|
||||
|
||||
bool _typeless;
|
||||
};
|
||||
|
||||
bool operator==(const InventorySlot& lhs, const InventorySlot& rhs);
|
||||
bool operator!=(const InventorySlot& lhs, const InventorySlot& rhs) { return (!(lhs == rhs)); }
|
||||
|
||||
} /*EQEmu*/
|
||||
|
||||
#endif /*COMMON_INVENTORY_SLOT*/
|
||||
+3073
File diff suppressed because it is too large
Load Diff
+544
@@ -0,0 +1,544 @@
|
||||
/* EQEMu: Everquest Server Emulator
|
||||
|
||||
Copyright (C) 2001-2016 EQEMu Development Team (http://eqemulator.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; version 2 of the License.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY except by those people which sell it, which
|
||||
are required to give you total support for your newly bought product;
|
||||
without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 04111-1307 USA
|
||||
*/
|
||||
|
||||
// @merth notes:
|
||||
// These classes could be optimized with database reads/writes by storing
|
||||
// a status flag indicating how object needs to interact with database
|
||||
|
||||
#ifndef COMMON_ITEM_H
|
||||
#define COMMON_ITEM_H
|
||||
|
||||
|
||||
class ItemParse; // Parses item packets
|
||||
class EvolveInfo; // Stores information about an evolving item family
|
||||
|
||||
#include "../common/eq_constants.h"
|
||||
#include "../common/item_base.h"
|
||||
#include "../common/timer.h"
|
||||
#include "../common/bodytypes.h"
|
||||
#include "../common/deity.h"
|
||||
#include "../common/memory_buffer.h"
|
||||
|
||||
#include <list>
|
||||
#include <map>
|
||||
|
||||
|
||||
namespace ItemField
|
||||
{
|
||||
enum
|
||||
{
|
||||
source = 0,
|
||||
#define F(x) x,
|
||||
#include "item_fieldlist.h"
|
||||
#undef F
|
||||
updated
|
||||
};
|
||||
};
|
||||
|
||||
// Specifies usage type for item inside ItemInst
|
||||
enum ItemInstTypes
|
||||
{
|
||||
ItemInstNormal = 0,
|
||||
ItemInstWorldContainer
|
||||
};
|
||||
|
||||
typedef enum {
|
||||
byFlagIgnore, //do not consider this flag
|
||||
byFlagSet, //apply action if the flag is set
|
||||
byFlagNotSet //apply action if the flag is NOT set
|
||||
} byFlagSetting;
|
||||
|
||||
|
||||
//FatherNitwit: location bits for searching specific
|
||||
//places with HasItem() and HasItemByUse()
|
||||
enum {
|
||||
invWhereWorn = 0x01,
|
||||
invWherePersonal = 0x02, //in the character's inventory
|
||||
invWhereBank = 0x04,
|
||||
invWhereSharedBank = 0x08,
|
||||
invWhereTrading = 0x10,
|
||||
invWhereCursor = 0x20
|
||||
};
|
||||
|
||||
class ItemInst;
|
||||
|
||||
// ########################################
|
||||
// Class: Queue
|
||||
// Queue that allows a read-only iterator
|
||||
class ItemInstQueue
|
||||
{
|
||||
public:
|
||||
~ItemInstQueue();
|
||||
/////////////////////////
|
||||
// Public Methods
|
||||
/////////////////////////
|
||||
|
||||
inline std::list<ItemInst*>::const_iterator cbegin() { return m_list.cbegin(); }
|
||||
inline std::list<ItemInst*>::const_iterator cend() { return m_list.cend(); }
|
||||
|
||||
inline int size() { return static_cast<int>(m_list.size()); } // TODO: change to size_t
|
||||
inline bool empty() { return m_list.empty(); }
|
||||
|
||||
void push(ItemInst* inst);
|
||||
void push_front(ItemInst* inst);
|
||||
ItemInst* pop();
|
||||
ItemInst* pop_back();
|
||||
ItemInst* peek_front() const;
|
||||
|
||||
protected:
|
||||
/////////////////////////
|
||||
// Protected Members
|
||||
/////////////////////////
|
||||
|
||||
std::list<ItemInst*> m_list;
|
||||
};
|
||||
|
||||
// ########################################
|
||||
// Class: Inventory
|
||||
// Character inventory
|
||||
class Inventory
|
||||
{
|
||||
friend class ItemInst;
|
||||
public:
|
||||
///////////////////////////////
|
||||
// Public Methods
|
||||
///////////////////////////////
|
||||
|
||||
Inventory() { m_inventory_version = EQEmu::versions::InventoryVersion::Unknown; m_inventory_version_set = false; }
|
||||
~Inventory();
|
||||
|
||||
// inv2 creep
|
||||
bool SetInventoryVersion(EQEmu::versions::InventoryVersion inventory_version) {
|
||||
if (!m_inventory_version_set) {
|
||||
m_inventory_version = EQEmu::versions::ValidateInventoryVersion(inventory_version);
|
||||
return (m_inventory_version_set = true);
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
bool SetInventoryVersion(EQEmu::versions::ClientVersion client_version) { return SetInventoryVersion(EQEmu::versions::ConvertClientVersionToInventoryVersion(client_version)); }
|
||||
|
||||
EQEmu::versions::InventoryVersion InventoryVersion() { return m_inventory_version; }
|
||||
|
||||
static void CleanDirty();
|
||||
static void MarkDirty(ItemInst *inst);
|
||||
|
||||
// Retrieve a writeable item at specified slot
|
||||
ItemInst* GetItem(int16 slot_id) const;
|
||||
ItemInst* GetItem(int16 slot_id, uint8 bagidx) const;
|
||||
|
||||
inline std::list<ItemInst*>::const_iterator cursor_cbegin() { return m_cursor.cbegin(); }
|
||||
inline std::list<ItemInst*>::const_iterator cursor_cend() { return m_cursor.cend(); }
|
||||
|
||||
inline int CursorSize() { return m_cursor.size(); }
|
||||
inline bool CursorEmpty() { return m_cursor.empty(); }
|
||||
|
||||
// Retrieve a read-only item from inventory
|
||||
inline const ItemInst* operator[](int16 slot_id) const { return GetItem(slot_id); }
|
||||
|
||||
// Add item to inventory
|
||||
int16 PutItem(int16 slot_id, const ItemInst& inst);
|
||||
|
||||
// Add item to cursor queue
|
||||
int16 PushCursor(const ItemInst& inst);
|
||||
|
||||
// Get cursor item in front of queue
|
||||
ItemInst* GetCursorItem();
|
||||
|
||||
// Swap items in inventory
|
||||
bool SwapItem(int16 slot_a, int16 slot_b);
|
||||
|
||||
// Remove item from inventory
|
||||
bool DeleteItem(int16 slot_id, uint8 quantity=0);
|
||||
|
||||
// Checks All items in a bag for No Drop
|
||||
bool CheckNoDrop(int16 slot_id);
|
||||
|
||||
// Remove item from inventory (and take control of memory)
|
||||
ItemInst* PopItem(int16 slot_id);
|
||||
|
||||
// Check whether there is space for the specified number of the specified item.
|
||||
bool HasSpaceForItem(const EQEmu::ItemBase *ItemToTry, int16 Quantity);
|
||||
|
||||
// Check whether item exists in inventory
|
||||
// where argument specifies OR'd list of invWhere constants to look
|
||||
int16 HasItem(uint32 item_id, uint8 quantity = 0, uint8 where = 0xFF);
|
||||
|
||||
// Check whether item exists in inventory
|
||||
// where argument specifies OR'd list of invWhere constants to look
|
||||
int16 HasItemByUse(uint8 use, uint8 quantity=0, uint8 where=0xFF);
|
||||
|
||||
// Check whether item exists in inventory
|
||||
// where argument specifies OR'd list of invWhere constants to look
|
||||
int16 HasItemByLoreGroup(uint32 loregroup, uint8 where=0xFF);
|
||||
|
||||
// Locate an available inventory slot
|
||||
int16 FindFreeSlot(bool for_bag, bool try_cursor, uint8 min_size = 0, bool is_arrow = false);
|
||||
int16 FindFreeSlotForTradeItem(const ItemInst* inst);
|
||||
|
||||
// Calculate slot_id for an item within a bag
|
||||
static int16 CalcSlotId(int16 slot_id); // Calc parent bag's slot_id
|
||||
static int16 CalcSlotId(int16 bagslot_id, uint8 bagidx); // Calc slot_id for item inside bag
|
||||
static uint8 CalcBagIdx(int16 slot_id); // Calc bagidx for slot_id
|
||||
static int16 CalcSlotFromMaterial(uint8 material);
|
||||
static uint8 CalcMaterialFromSlot(int16 equipslot);
|
||||
|
||||
static bool CanItemFitInContainer(const EQEmu::ItemBase *ItemToTry, const EQEmu::ItemBase *Container);
|
||||
|
||||
// Test for valid inventory casting slot
|
||||
bool SupportsClickCasting(int16 slot_id);
|
||||
bool SupportsPotionBeltCasting(int16 slot_id);
|
||||
|
||||
// Test whether a given slot can support a container item
|
||||
static bool SupportsContainers(int16 slot_id);
|
||||
|
||||
int GetSlotByItemInst(ItemInst *inst);
|
||||
|
||||
uint8 FindBrightestLightType();
|
||||
|
||||
void dumpEntireInventory();
|
||||
void dumpWornItems();
|
||||
void dumpInventory();
|
||||
void dumpBankItems();
|
||||
void dumpSharedBankItems();
|
||||
|
||||
void SetCustomItemData(uint32 character_id, int16 slot_id, std::string identifier, std::string value);
|
||||
void SetCustomItemData(uint32 character_id, int16 slot_id, std::string identifier, int value);
|
||||
void SetCustomItemData(uint32 character_id, int16 slot_id, std::string identifier, float value);
|
||||
void SetCustomItemData(uint32 character_id, int16 slot_id, std::string identifier, bool value);
|
||||
std::string GetCustomItemData(int16 slot_id, std::string identifier);
|
||||
protected:
|
||||
///////////////////////////////
|
||||
// Protected Methods
|
||||
///////////////////////////////
|
||||
|
||||
int GetSlotByItemInstCollection(const std::map<int16, ItemInst*> &collection, ItemInst *inst);
|
||||
void dumpItemCollection(const std::map<int16, ItemInst*> &collection);
|
||||
void dumpBagContents(ItemInst *inst, std::map<int16, ItemInst*>::const_iterator *it);
|
||||
|
||||
// Retrieves item within an inventory bucket
|
||||
ItemInst* _GetItem(const std::map<int16, ItemInst*>& bucket, int16 slot_id) const;
|
||||
|
||||
// Private "put" item into bucket, without regard for what is currently in bucket
|
||||
int16 _PutItem(int16 slot_id, ItemInst* inst);
|
||||
|
||||
// Checks an inventory bucket for a particular item
|
||||
int16 _HasItem(std::map<int16, ItemInst*>& bucket, uint32 item_id, uint8 quantity);
|
||||
int16 _HasItem(ItemInstQueue& iqueue, uint32 item_id, uint8 quantity);
|
||||
int16 _HasItemByUse(std::map<int16, ItemInst*>& bucket, uint8 use, uint8 quantity);
|
||||
int16 _HasItemByUse(ItemInstQueue& iqueue, uint8 use, uint8 quantity);
|
||||
int16 _HasItemByLoreGroup(std::map<int16, ItemInst*>& bucket, uint32 loregroup);
|
||||
int16 _HasItemByLoreGroup(ItemInstQueue& iqueue, uint32 loregroup);
|
||||
|
||||
|
||||
// Player inventory
|
||||
std::map<int16, ItemInst*> m_worn; // Items worn by character
|
||||
std::map<int16, ItemInst*> m_inv; // Items in character personal inventory
|
||||
std::map<int16, ItemInst*> m_bank; // Items in character bank
|
||||
std::map<int16, ItemInst*> m_shbank; // Items in character shared bank
|
||||
std::map<int16, ItemInst*> m_trade; // Items in a trade session
|
||||
ItemInstQueue m_cursor; // Items on cursor: FIFO
|
||||
|
||||
private:
|
||||
// Active inventory version
|
||||
EQEmu::versions::InventoryVersion m_inventory_version;
|
||||
bool m_inventory_version_set;
|
||||
};
|
||||
|
||||
class SharedDatabase;
|
||||
|
||||
// ########################################
|
||||
// Class: ItemInst
|
||||
// Base class for an instance of an item
|
||||
// An item instance encapsulates item data + data specific
|
||||
// to an item instance (includes dye, augments, charges, etc)
|
||||
class ItemInst
|
||||
{
|
||||
public:
|
||||
/////////////////////////
|
||||
// Methods
|
||||
/////////////////////////
|
||||
|
||||
// Constructors/Destructor
|
||||
ItemInst(const EQEmu::ItemBase* item = nullptr, int16 charges = 0);
|
||||
|
||||
ItemInst(SharedDatabase *db, uint32 item_id, int16 charges = 0);
|
||||
|
||||
ItemInst(ItemInstTypes use_type);
|
||||
|
||||
ItemInst(const ItemInst& copy);
|
||||
|
||||
~ItemInst();
|
||||
|
||||
// Query item type
|
||||
bool IsType(EQEmu::item::ItemClass item_class) const;
|
||||
|
||||
bool IsClassCommon();
|
||||
bool IsClassBag();
|
||||
bool IsClassBook();
|
||||
|
||||
bool IsClassCommon() const { return const_cast<ItemInst*>(this)->IsClassCommon(); }
|
||||
bool IsClassBag() const { return const_cast<ItemInst*>(this)->IsClassBag(); }
|
||||
bool IsClassBook() const { return const_cast<ItemInst*>(this)->IsClassBook(); }
|
||||
|
||||
// Can item be stacked?
|
||||
bool IsStackable() const;
|
||||
bool IsCharged() const;
|
||||
|
||||
// Can item be equipped by/at?
|
||||
bool IsEquipable(uint16 race, uint16 class_) const;
|
||||
bool IsEquipable(int16 slot_id) const;
|
||||
|
||||
//
|
||||
// Augments
|
||||
//
|
||||
bool IsAugmentable() const;
|
||||
bool AvailableWearSlot(uint32 aug_wear_slots) const;
|
||||
int8 AvailableAugmentSlot(int32 augtype) const;
|
||||
bool IsAugmentSlotAvailable(int32 augtype, uint8 slot) const;
|
||||
inline int32 GetAugmentType() const { return ((m_item) ? m_item->AugType : NO_ITEM); }
|
||||
|
||||
inline bool IsExpendable() const { return ((m_item) ? ((m_item->Click.Type == EQEmu::item::ItemEffectExpendable) || (m_item->ItemType == EQEmu::item::ItemTypePotion)) : false); }
|
||||
|
||||
//
|
||||
// Contents
|
||||
//
|
||||
ItemInst* GetItem(uint8 slot) const;
|
||||
uint32 GetItemID(uint8 slot) const;
|
||||
inline const ItemInst* operator[](uint8 slot) const { return GetItem(slot); }
|
||||
void PutItem(uint8 slot, const ItemInst& inst);
|
||||
void PutItem(SharedDatabase *db, uint8 slot, uint32 item_id) { return; } // not defined anywhere...
|
||||
void DeleteItem(uint8 slot);
|
||||
ItemInst* PopItem(uint8 index);
|
||||
void Clear();
|
||||
void ClearByFlags(byFlagSetting is_nodrop, byFlagSetting is_norent);
|
||||
uint8 FirstOpenSlot() const;
|
||||
uint8 GetTotalItemCount() const;
|
||||
bool IsNoneEmptyContainer();
|
||||
std::map<uint8, ItemInst*>* GetContents() { return &m_contents; }
|
||||
|
||||
//
|
||||
// Augments
|
||||
//
|
||||
ItemInst* GetAugment(uint8 slot) const;
|
||||
uint32 GetAugmentItemID(uint8 slot) const;
|
||||
void PutAugment(uint8 slot, const ItemInst& inst);
|
||||
void PutAugment(SharedDatabase *db, uint8 slot, uint32 item_id);
|
||||
void DeleteAugment(uint8 slot);
|
||||
ItemInst* RemoveAugment(uint8 index);
|
||||
bool IsAugmented();
|
||||
ItemInst* GetOrnamentationAug(int32 ornamentationAugtype) const;
|
||||
bool UpdateOrnamentationInfo();
|
||||
static bool CanTransform(const EQEmu::ItemBase *ItemToTry, const EQEmu::ItemBase *Container, bool AllowAll = false);
|
||||
|
||||
// Has attack/delay?
|
||||
bool IsWeapon() const;
|
||||
bool IsAmmo() const;
|
||||
|
||||
// Accessors
|
||||
const uint32 GetID() const { return ((m_item) ? m_item->ID : NO_ITEM); }
|
||||
const uint32 GetItemScriptID() const { return ((m_item) ? m_item->ScriptFileID : NO_ITEM); }
|
||||
const EQEmu::ItemBase* GetItem() const;
|
||||
const EQEmu::ItemBase* GetUnscaledItem() const;
|
||||
|
||||
int16 GetCharges() const { return m_charges; }
|
||||
void SetCharges(int16 charges) { m_charges = charges; }
|
||||
|
||||
uint32 GetPrice() const { return m_price; }
|
||||
void SetPrice(uint32 price) { m_price = price; }
|
||||
|
||||
void SetColor(uint32 color) { m_color = color; }
|
||||
uint32 GetColor() const { return m_color; }
|
||||
|
||||
uint32 GetMerchantSlot() const { return m_merchantslot; }
|
||||
void SetMerchantSlot(uint32 slot) { m_merchantslot = slot; }
|
||||
|
||||
int32 GetMerchantCount() const { return m_merchantcount; }
|
||||
void SetMerchantCount(int32 count) { m_merchantcount = count; }
|
||||
|
||||
int16 GetCurrentSlot() const { return m_currentslot; }
|
||||
void SetCurrentSlot(int16 curr_slot) { m_currentslot = curr_slot; }
|
||||
|
||||
// Is this item already attuned?
|
||||
bool IsAttuned() const { return m_attuned; }
|
||||
void SetAttuned(bool flag) { m_attuned=flag; }
|
||||
|
||||
std::string GetCustomDataString() const;
|
||||
std::string GetCustomData(std::string identifier);
|
||||
void SetCustomData(std::string identifier, std::string value);
|
||||
void SetCustomData(std::string identifier, int value);
|
||||
void SetCustomData(std::string identifier, float value);
|
||||
void SetCustomData(std::string identifier, bool value);
|
||||
void DeleteCustomData(std::string identifier);
|
||||
|
||||
// Allows treatment of this object as though it were a pointer to m_item
|
||||
operator bool() const { return (m_item != nullptr); }
|
||||
|
||||
// Compare inner Item_Struct of two ItemInst objects
|
||||
bool operator==(const ItemInst& right) const { return (this->m_item == right.m_item); }
|
||||
bool operator!=(const ItemInst& right) const { return (this->m_item != right.m_item); }
|
||||
|
||||
// Clone current item
|
||||
ItemInst* Clone() const;
|
||||
|
||||
bool IsSlotAllowed(int16 slot_id) const;
|
||||
|
||||
bool IsScaling() const { return m_scaling; }
|
||||
bool IsEvolving() const { return (m_evolveLvl >= 1); }
|
||||
uint32 GetExp() const { return m_exp; }
|
||||
void SetExp(uint32 exp) { m_exp = exp; }
|
||||
void AddExp(uint32 exp) { m_exp += exp; }
|
||||
bool IsActivated() { return m_activated; }
|
||||
void SetActivated(bool activated) { m_activated = activated; }
|
||||
int8 GetEvolveLvl() const { return m_evolveLvl; }
|
||||
void SetScaling(bool v) { m_scaling = v; }
|
||||
uint32 GetOrnamentationIcon() const { return m_ornamenticon; }
|
||||
void SetOrnamentIcon(uint32 ornament_icon) { m_ornamenticon = ornament_icon; }
|
||||
uint32 GetOrnamentationIDFile() const { return m_ornamentidfile; }
|
||||
void SetOrnamentationIDFile(uint32 ornament_idfile) { m_ornamentidfile = ornament_idfile; }
|
||||
uint32 GetOrnamentHeroModel(int32 material_slot = -1) const;
|
||||
void SetOrnamentHeroModel(uint32 ornament_hero_model) { m_ornament_hero_model = ornament_hero_model; }
|
||||
uint32 GetRecastTimestamp() const { return m_recast_timestamp; }
|
||||
void SetRecastTimestamp(uint32 in) { m_recast_timestamp = in; }
|
||||
|
||||
void Initialize(SharedDatabase *db = nullptr);
|
||||
void ScaleItem();
|
||||
bool EvolveOnAllKills() const;
|
||||
int8 GetMaxEvolveLvl() const;
|
||||
uint32 GetKillsNeeded(uint8 currentlevel);
|
||||
|
||||
std::string Serialize(int16 slot_id) const { EQEmu::InternalSerializedItem_Struct s; s.slot_id = slot_id; s.inst = (const void*)this; std::string ser; ser.assign((char*)&s, sizeof(EQEmu::InternalSerializedItem_Struct)); return ser; }
|
||||
void Serialize(EQEmu::OutBuffer& ob, int16 slot_id) const { EQEmu::InternalSerializedItem_Struct isi; isi.slot_id = slot_id; isi.inst = (const void*)this; ob.write((const char*)&isi, sizeof(isi)); }
|
||||
|
||||
inline int32 GetSerialNumber() const { return m_SerialNumber; }
|
||||
inline void SetSerialNumber(int32 id) { m_SerialNumber = id; }
|
||||
|
||||
std::map<std::string, Timer>& GetTimers() { return m_timers; }
|
||||
void SetTimer(std::string name, uint32 time);
|
||||
void StopTimer(std::string name);
|
||||
void ClearTimers();
|
||||
|
||||
// Get a total of a stat, including augs
|
||||
// These functions should be used in place of other code manually totaling
|
||||
// to centralize where it is done to make future changes easier (ex. whenever powersources come around)
|
||||
// and to minimize errors. CalcItemBonuses however doesn't use these in interest of performance
|
||||
// by default these do not recurse into augs
|
||||
int GetItemArmorClass(bool augments = false) const;
|
||||
int GetItemElementalDamage(int &magic, int &fire, int &cold, int &poison, int &disease, int &chromatic, int &prismatic, int &physical, int &corruption, bool augments = false) const;
|
||||
// These two differ in the fact that they're quick checks (they are checked BEFORE the one above
|
||||
int GetItemElementalFlag(bool augments = false) const;
|
||||
int GetItemElementalDamage(bool augments = false) const;
|
||||
int GetItemRecommendedLevel(bool augments = false) const;
|
||||
int GetItemRequiredLevel(bool augments = false) const;
|
||||
int GetItemWeaponDamage(bool augments = false) const;
|
||||
int GetItemBackstabDamage(bool augments = false) const;
|
||||
// these two are just quick checks
|
||||
int GetItemBaneDamageBody(bool augments = false) const;
|
||||
int GetItemBaneDamageRace(bool augments = false) const;
|
||||
int GetItemBaneDamageBody(bodyType against, bool augments = false) const;
|
||||
int GetItemBaneDamageRace(uint16 against, bool augments = false) const;
|
||||
int GetItemMagical(bool augments = false) const;
|
||||
int GetItemHP(bool augments = false) const;
|
||||
int GetItemMana(bool augments = false) const;
|
||||
int GetItemEndur(bool augments = false) const;
|
||||
int GetItemAttack(bool augments = false) const;
|
||||
int GetItemStr(bool augments = false) const;
|
||||
int GetItemSta(bool augments = false) const;
|
||||
int GetItemDex(bool augments = false) const;
|
||||
int GetItemAgi(bool augments = false) const;
|
||||
int GetItemInt(bool augments = false) const;
|
||||
int GetItemWis(bool augments = false) const;
|
||||
int GetItemCha(bool augments = false) const;
|
||||
int GetItemMR(bool augments = false) const;
|
||||
int GetItemFR(bool augments = false) const;
|
||||
int GetItemCR(bool augments = false) const;
|
||||
int GetItemPR(bool augments = false) const;
|
||||
int GetItemDR(bool augments = false) const;
|
||||
int GetItemCorrup(bool augments = false) const;
|
||||
int GetItemHeroicStr(bool augments = false) const;
|
||||
int GetItemHeroicSta(bool augments = false) const;
|
||||
int GetItemHeroicDex(bool augments = false) const;
|
||||
int GetItemHeroicAgi(bool augments = false) const;
|
||||
int GetItemHeroicInt(bool augments = false) const;
|
||||
int GetItemHeroicWis(bool augments = false) const;
|
||||
int GetItemHeroicCha(bool augments = false) const;
|
||||
int GetItemHeroicMR(bool augments = false) const;
|
||||
int GetItemHeroicFR(bool augments = false) const;
|
||||
int GetItemHeroicCR(bool augments = false) const;
|
||||
int GetItemHeroicPR(bool augments = false) const;
|
||||
int GetItemHeroicDR(bool augments = false) const;
|
||||
int GetItemHeroicCorrup(bool augments = false) const;
|
||||
int GetItemHaste(bool augments = false) const;
|
||||
|
||||
protected:
|
||||
//////////////////////////
|
||||
// Protected Members
|
||||
//////////////////////////
|
||||
std::map<uint8, ItemInst*>::const_iterator _cbegin() { return m_contents.cbegin(); }
|
||||
std::map<uint8, ItemInst*>::const_iterator _cend() { return m_contents.cend(); }
|
||||
|
||||
friend class Inventory;
|
||||
|
||||
|
||||
void _PutItem(uint8 index, ItemInst* inst) { m_contents[index] = inst; }
|
||||
|
||||
ItemInstTypes m_use_type; // Usage type for item
|
||||
const EQEmu::ItemBase* m_item; // Ptr to item data
|
||||
int16 m_charges; // # of charges for chargeable items
|
||||
uint32 m_price; // Bazaar /trader price
|
||||
uint32 m_color;
|
||||
uint32 m_merchantslot;
|
||||
int16 m_currentslot;
|
||||
bool m_attuned;
|
||||
int32 m_merchantcount; //number avaliable on the merchant, -1=unlimited
|
||||
int32 m_SerialNumber; // Unique identifier for this instance of an item. Needed for Bazaar.
|
||||
uint32 m_exp;
|
||||
int8 m_evolveLvl;
|
||||
bool m_activated;
|
||||
EQEmu::ItemBase* m_scaledItem;
|
||||
EvolveInfo* m_evolveInfo;
|
||||
bool m_scaling;
|
||||
uint32 m_ornamenticon;
|
||||
uint32 m_ornamentidfile;
|
||||
uint32 m_ornament_hero_model;
|
||||
uint32 m_recast_timestamp;
|
||||
|
||||
//
|
||||
// Items inside of this item (augs or contents);
|
||||
std::map<uint8, ItemInst*> m_contents; // Zero-based index: min=0, max=9
|
||||
std::map<std::string, std::string> m_custom_data;
|
||||
std::map<std::string, Timer> m_timers;
|
||||
};
|
||||
|
||||
class EvolveInfo {
|
||||
public:
|
||||
friend class ItemInst;
|
||||
//temporary
|
||||
uint16 LvlKills[9];
|
||||
uint32 FirstItem;
|
||||
uint8 MaxLvl;
|
||||
bool AllKills;
|
||||
|
||||
EvolveInfo();
|
||||
EvolveInfo(uint32 first, uint8 max, bool allkills, uint32 L2, uint32 L3, uint32 L4, uint32 L5, uint32 L6, uint32 L7, uint32 L8, uint32 L9, uint32 L10);
|
||||
~EvolveInfo();
|
||||
};
|
||||
|
||||
#endif /*COMMON_ITEM_H*/
|
||||
@@ -17,7 +17,7 @@
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include "item_data.h"
|
||||
#include "item_base.h"
|
||||
#include "classes.h"
|
||||
#include "races.h"
|
||||
//#include "deity.h"
|
||||
@@ -167,7 +167,7 @@ uint8 EQEmu::item::ConvertAugTypeBitToAugType(uint32 aug_type_bit)
|
||||
}
|
||||
}
|
||||
|
||||
bool EQEmu::ItemData::IsEquipable(uint16 race_id, uint16 class_id) const
|
||||
bool EQEmu::ItemBase::IsEquipable(uint16 race_id, uint16 class_id)
|
||||
{
|
||||
if (!(Races & GetPlayerRaceBit(race_id)))
|
||||
return false;
|
||||
@@ -178,32 +178,32 @@ bool EQEmu::ItemData::IsEquipable(uint16 race_id, uint16 class_id) const
|
||||
return true;
|
||||
}
|
||||
|
||||
bool EQEmu::ItemData::IsClassCommon() const
|
||||
bool EQEmu::ItemBase::IsClassCommon()
|
||||
{
|
||||
return (ItemClass == item::ItemClassCommon);
|
||||
}
|
||||
|
||||
bool EQEmu::ItemData::IsClassBag() const
|
||||
bool EQEmu::ItemBase::IsClassBag()
|
||||
{
|
||||
return (ItemClass == item::ItemClassBag);
|
||||
}
|
||||
|
||||
bool EQEmu::ItemData::IsClassBook() const
|
||||
bool EQEmu::ItemBase::IsClassBook()
|
||||
{
|
||||
return (ItemClass == item::ItemClassBook);
|
||||
}
|
||||
|
||||
bool EQEmu::ItemData::IsType1HWeapon() const
|
||||
bool EQEmu::ItemBase::IsType1HWeapon()
|
||||
{
|
||||
return ((ItemType == item::ItemType1HBlunt) || (ItemType == item::ItemType1HSlash) || (ItemType == item::ItemType1HPiercing));
|
||||
}
|
||||
|
||||
bool EQEmu::ItemData::IsType2HWeapon() const
|
||||
bool EQEmu::ItemBase::IsType2HWeapon()
|
||||
{
|
||||
return ((ItemType == item::ItemType2HBlunt) || (ItemType == item::ItemType2HSlash) || (ItemType == item::ItemType2HPiercing));
|
||||
}
|
||||
|
||||
bool EQEmu::ItemData::IsTypeShield() const
|
||||
bool EQEmu::ItemBase::IsTypeShield()
|
||||
{
|
||||
return (ItemType == item::ItemTypeShield);
|
||||
}
|
||||
@@ -17,8 +17,8 @@
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 04111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef COMMON_ITEM_DATA_H
|
||||
#define COMMON_ITEM_DATA_H
|
||||
#ifndef COMMON_ITEM_BASE_H
|
||||
#define COMMON_ITEM_BASE_H
|
||||
|
||||
|
||||
/*
|
||||
@@ -50,6 +50,17 @@
|
||||
namespace EQEmu
|
||||
{
|
||||
namespace item {
|
||||
enum ItemAttributeBit : uint32 {
|
||||
bit_ItemAttributeNone = 0x00000000,
|
||||
bit_ItemAttributeLore = 0x00000001,
|
||||
bit_ItemAttributeArtifact = 0x00000002,
|
||||
bit_ItemAttributeSummoned = 0x00000004,
|
||||
bit_ItemAttributeMagic = 0x00000008,
|
||||
bit_ItemAttributeAugment = 0x00000010,
|
||||
bit_ItemAttributePendingLore = 0x00000020,
|
||||
bit_ItemAttributeUnknown = 0xFFFFFFFF
|
||||
};
|
||||
|
||||
enum ItemClass {
|
||||
ItemClassCommon = 0,
|
||||
ItemClassBag,
|
||||
@@ -343,8 +354,8 @@ namespace EQEmu
|
||||
//ProcRate
|
||||
};
|
||||
|
||||
uint32 ConvertAugTypeToAugTypeBit(uint8 aug_type);
|
||||
uint8 ConvertAugTypeBitToAugType(uint32 aug_type_bit);
|
||||
extern uint32 ConvertAugTypeToAugTypeBit(uint8 aug_type);
|
||||
extern uint8 ConvertAugTypeBitToAugType(uint32 aug_type_bit);
|
||||
|
||||
} /*item*/
|
||||
|
||||
@@ -353,9 +364,10 @@ namespace EQEmu
|
||||
const void * inst;
|
||||
};
|
||||
|
||||
struct ItemData {
|
||||
struct ItemBase {
|
||||
// Non packet based fields
|
||||
uint8 MinStatus;
|
||||
uint8 ItemDataType; // memset to item::ItemDataBase ('0') during mmf load
|
||||
|
||||
// Packet based fields
|
||||
uint8 ItemClass; // Item Type: 0=common, 1=container, 2=book
|
||||
@@ -464,9 +476,9 @@ namespace EQEmu
|
||||
int32 FactionAmt4; // Faction Amt 4
|
||||
char CharmFile[32]; // ?
|
||||
uint32 AugType;
|
||||
uint8 AugSlotType[inventory::SocketCount]; // RoF: Augment Slot 1-6 Type
|
||||
uint8 AugSlotVisible[inventory::SocketCount]; // RoF: Augment Slot 1-6 Visible
|
||||
uint8 AugSlotUnk2[inventory::SocketCount]; // RoF: Augment Slot 1-6 Unknown Most likely Powersource related
|
||||
uint8 AugSlotType[EQEmu::legacy::ITEM_COMMON_SIZE]; // RoF: Augment Slot 1-6 Type
|
||||
uint8 AugSlotVisible[EQEmu::legacy::ITEM_COMMON_SIZE]; // RoF: Augment Slot 1-6 Visible
|
||||
uint8 AugSlotUnk2[EQEmu::legacy::ITEM_COMMON_SIZE]; // RoF: Augment Slot 1-6 Unknown Most likely Powersource related
|
||||
uint32 LDoNTheme;
|
||||
uint32 LDoNPrice;
|
||||
uint32 LDoNSold;
|
||||
@@ -531,15 +543,23 @@ namespace EQEmu
|
||||
char ScrollName[65];
|
||||
//BardName
|
||||
|
||||
bool IsEquipable(uint16 Race, uint16 Class) const;
|
||||
bool IsClassCommon() const;
|
||||
bool IsClassBag() const;
|
||||
bool IsClassBook() const;
|
||||
bool IsType1HWeapon() const;
|
||||
bool IsType2HWeapon() const;
|
||||
bool IsTypeShield() const;
|
||||
bool IsEquipable(uint16 Race, uint16 Class);
|
||||
bool IsClassCommon();
|
||||
bool IsClassBag();
|
||||
bool IsClassBook();
|
||||
bool IsType1HWeapon();
|
||||
bool IsType2HWeapon();
|
||||
bool IsTypeShield();
|
||||
|
||||
bool IsEquipable(uint16 Race, uint16 Class) const { return const_cast<ItemBase*>(this)->IsEquipable(Race, Class); }
|
||||
bool IsClassCommon() const { return const_cast<ItemBase*>(this)->IsClassCommon(); }
|
||||
bool IsClassBag() const { return const_cast<ItemBase*>(this)->IsClassBag(); }
|
||||
bool IsClassBook() const { return const_cast<ItemBase*>(this)->IsClassBook(); }
|
||||
bool IsType1HWeapon() const { return const_cast<ItemBase*>(this)->IsType1HWeapon(); }
|
||||
bool IsType2HWeapon() const { return const_cast<ItemBase*>(this)->IsType2HWeapon(); }
|
||||
bool IsTypeShield() const { return const_cast<ItemBase*>(this)->IsTypeShield(); }
|
||||
};
|
||||
|
||||
} /*EQEmu*/
|
||||
|
||||
#endif /*COMMON_ITEM_DATA_H*/
|
||||
#endif /*COMMON_ITEM_BASE_H*/
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,334 +0,0 @@
|
||||
/* EQEMu: Everquest Server Emulator
|
||||
|
||||
Copyright (C) 2001-2016 EQEMu Development Team (http://eqemulator.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; version 2 of the License.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY except by those people which sell it, which
|
||||
are required to give you total support for your newly bought product;
|
||||
without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 04111-1307 USA
|
||||
*/
|
||||
|
||||
// @merth notes:
|
||||
// These classes could be optimized with database reads/writes by storing
|
||||
// a status flag indicating how object needs to interact with database
|
||||
|
||||
#ifndef COMMON_ITEM_INSTANCE_H
|
||||
#define COMMON_ITEM_INSTANCE_H
|
||||
|
||||
|
||||
class ItemParse; // Parses item packets
|
||||
class EvolveInfo; // Stores information about an evolving item family
|
||||
|
||||
#include "../common/eq_constants.h"
|
||||
#include "../common/item_data.h"
|
||||
#include "../common/timer.h"
|
||||
#include "../common/bodytypes.h"
|
||||
#include "../common/deity.h"
|
||||
#include "../common/memory_buffer.h"
|
||||
|
||||
#include <map>
|
||||
|
||||
|
||||
// Specifies usage type for item inside EQEmu::ItemInstance
|
||||
enum ItemInstTypes
|
||||
{
|
||||
ItemInstNormal = 0,
|
||||
ItemInstWorldContainer
|
||||
};
|
||||
|
||||
typedef enum {
|
||||
byFlagIgnore, //do not consider this flag
|
||||
byFlagSet, //apply action if the flag is set
|
||||
byFlagNotSet //apply action if the flag is NOT set
|
||||
} byFlagSetting;
|
||||
|
||||
class SharedDatabase;
|
||||
|
||||
// ########################################
|
||||
// Class: EQEmu::ItemInstance
|
||||
// Base class for an instance of an item
|
||||
// An item instance encapsulates item data + data specific
|
||||
// to an item instance (includes dye, augments, charges, etc)
|
||||
namespace EQEmu
|
||||
{
|
||||
class InventoryProfile;
|
||||
|
||||
class ItemInstance {
|
||||
public:
|
||||
/////////////////////////
|
||||
// Methods
|
||||
/////////////////////////
|
||||
|
||||
// Constructors/Destructor
|
||||
ItemInstance(const ItemData* item = nullptr, int16 charges = 0);
|
||||
|
||||
ItemInstance(SharedDatabase *db, uint32 item_id, int16 charges = 0);
|
||||
|
||||
ItemInstance(ItemInstTypes use_type);
|
||||
|
||||
ItemInstance(const ItemInstance& copy);
|
||||
|
||||
~ItemInstance();
|
||||
|
||||
// Query item type
|
||||
bool IsType(item::ItemClass item_class) const;
|
||||
|
||||
bool IsClassCommon() const;
|
||||
bool IsClassBag() const;
|
||||
bool IsClassBook() const;
|
||||
|
||||
// Can item be stacked?
|
||||
bool IsStackable() const;
|
||||
bool IsCharged() const;
|
||||
|
||||
// Can item be equipped by/at?
|
||||
bool IsEquipable(uint16 race, uint16 class_) const;
|
||||
bool IsEquipable(int16 slot_id) const;
|
||||
|
||||
//
|
||||
// Augments
|
||||
//
|
||||
bool IsAugmentable() const;
|
||||
bool AvailableWearSlot(uint32 aug_wear_slots) const;
|
||||
int8 AvailableAugmentSlot(int32 augtype) const;
|
||||
bool IsAugmentSlotAvailable(int32 augtype, uint8 slot) const;
|
||||
inline int32 GetAugmentType() const { return ((m_item) ? m_item->AugType : 0); }
|
||||
|
||||
inline bool IsExpendable() const { return ((m_item) ? ((m_item->Click.Type == item::ItemEffectExpendable) || (m_item->ItemType == item::ItemTypePotion)) : false); }
|
||||
|
||||
//
|
||||
// Contents
|
||||
//
|
||||
ItemInstance* GetItem(uint8 slot) const;
|
||||
uint32 GetItemID(uint8 slot) const;
|
||||
inline const ItemInstance* operator[](uint8 slot) const { return GetItem(slot); }
|
||||
void PutItem(uint8 slot, const ItemInstance& inst);
|
||||
void PutItem(SharedDatabase *db, uint8 slot, uint32 item_id) { return; } // not defined anywhere...
|
||||
void DeleteItem(uint8 slot);
|
||||
ItemInstance* PopItem(uint8 index);
|
||||
void Clear();
|
||||
void ClearByFlags(byFlagSetting is_nodrop, byFlagSetting is_norent);
|
||||
uint8 FirstOpenSlot() const;
|
||||
uint8 GetTotalItemCount() const;
|
||||
bool IsNoneEmptyContainer();
|
||||
std::map<uint8, ItemInstance*>* GetContents() { return &m_contents; }
|
||||
|
||||
//
|
||||
// Augments
|
||||
//
|
||||
ItemInstance* GetAugment(uint8 slot) const;
|
||||
uint32 GetAugmentItemID(uint8 slot) const;
|
||||
void PutAugment(uint8 slot, const ItemInstance& inst);
|
||||
void PutAugment(SharedDatabase *db, uint8 slot, uint32 item_id);
|
||||
void DeleteAugment(uint8 slot);
|
||||
ItemInstance* RemoveAugment(uint8 index);
|
||||
bool IsAugmented();
|
||||
ItemInstance* GetOrnamentationAug(int32 ornamentationAugtype) const;
|
||||
bool UpdateOrnamentationInfo();
|
||||
static bool CanTransform(const ItemData *ItemToTry, const ItemData *Container, bool AllowAll = false);
|
||||
|
||||
// Has attack/delay?
|
||||
bool IsWeapon() const;
|
||||
bool IsAmmo() const;
|
||||
|
||||
// Accessors
|
||||
const uint32 GetID() const { return ((m_item) ? m_item->ID : 0); }
|
||||
const uint32 GetItemScriptID() const { return ((m_item) ? m_item->ScriptFileID : 0); }
|
||||
const ItemData* GetItem() const;
|
||||
const ItemData* GetUnscaledItem() const;
|
||||
|
||||
int16 GetCharges() const { return m_charges; }
|
||||
void SetCharges(int16 charges) { m_charges = charges; }
|
||||
|
||||
uint32 GetPrice() const { return m_price; }
|
||||
void SetPrice(uint32 price) { m_price = price; }
|
||||
|
||||
void SetColor(uint32 color) { m_color = color; }
|
||||
uint32 GetColor() const { return m_color; }
|
||||
|
||||
uint32 GetMerchantSlot() const { return m_merchantslot; }
|
||||
void SetMerchantSlot(uint32 slot) { m_merchantslot = slot; }
|
||||
|
||||
int32 GetMerchantCount() const { return m_merchantcount; }
|
||||
void SetMerchantCount(int32 count) { m_merchantcount = count; }
|
||||
|
||||
int16 GetCurrentSlot() const { return m_currentslot; }
|
||||
void SetCurrentSlot(int16 curr_slot) { m_currentslot = curr_slot; }
|
||||
|
||||
// Is this item already attuned?
|
||||
bool IsAttuned() const { return m_attuned; }
|
||||
void SetAttuned(bool flag) { m_attuned = flag; }
|
||||
|
||||
std::string GetCustomDataString() const;
|
||||
std::string GetCustomData(std::string identifier);
|
||||
void SetCustomData(std::string identifier, std::string value);
|
||||
void SetCustomData(std::string identifier, int value);
|
||||
void SetCustomData(std::string identifier, float value);
|
||||
void SetCustomData(std::string identifier, bool value);
|
||||
void DeleteCustomData(std::string identifier);
|
||||
|
||||
// Allows treatment of this object as though it were a pointer to m_item
|
||||
operator bool() const { return (m_item != nullptr); }
|
||||
|
||||
// Compare inner Item_Struct of two ItemInstance objects
|
||||
bool operator==(const ItemInstance& right) const { return (this->m_item == right.m_item); }
|
||||
bool operator!=(const ItemInstance& right) const { return (this->m_item != right.m_item); }
|
||||
|
||||
// Clone current item
|
||||
ItemInstance* Clone() const;
|
||||
|
||||
bool IsSlotAllowed(int16 slot_id) const;
|
||||
|
||||
bool IsDroppable(bool recurse = true) const;
|
||||
|
||||
bool IsScaling() const { return m_scaling; }
|
||||
bool IsEvolving() const { return (m_evolveLvl >= 1); }
|
||||
uint32 GetExp() const { return m_exp; }
|
||||
void SetExp(uint32 exp) { m_exp = exp; }
|
||||
void AddExp(uint32 exp) { m_exp += exp; }
|
||||
bool IsActivated() { return m_activated; }
|
||||
void SetActivated(bool activated) { m_activated = activated; }
|
||||
int8 GetEvolveLvl() const { return m_evolveLvl; }
|
||||
void SetScaling(bool v) { m_scaling = v; }
|
||||
uint32 GetOrnamentationIcon() const { return m_ornamenticon; }
|
||||
void SetOrnamentIcon(uint32 ornament_icon) { m_ornamenticon = ornament_icon; }
|
||||
uint32 GetOrnamentationIDFile() const { return m_ornamentidfile; }
|
||||
void SetOrnamentationIDFile(uint32 ornament_idfile) { m_ornamentidfile = ornament_idfile; }
|
||||
uint32 GetOrnamentHeroModel(int32 material_slot = -1) const;
|
||||
void SetOrnamentHeroModel(uint32 ornament_hero_model) { m_ornament_hero_model = ornament_hero_model; }
|
||||
uint32 GetRecastTimestamp() const { return m_recast_timestamp; }
|
||||
void SetRecastTimestamp(uint32 in) { m_recast_timestamp = in; }
|
||||
|
||||
void Initialize(SharedDatabase *db = nullptr);
|
||||
void ScaleItem();
|
||||
bool EvolveOnAllKills() const;
|
||||
int8 GetMaxEvolveLvl() const;
|
||||
uint32 GetKillsNeeded(uint8 currentlevel);
|
||||
|
||||
std::string Serialize(int16 slot_id) const { InternalSerializedItem_Struct s; s.slot_id = slot_id; s.inst = (const void*)this; std::string ser; ser.assign((char*)&s, sizeof(InternalSerializedItem_Struct)); return ser; }
|
||||
void Serialize(OutBuffer& ob, int16 slot_id) const { InternalSerializedItem_Struct isi; isi.slot_id = slot_id; isi.inst = (const void*)this; ob.write((const char*)&isi, sizeof(isi)); }
|
||||
|
||||
inline int32 GetSerialNumber() const { return m_SerialNumber; }
|
||||
inline void SetSerialNumber(int32 id) { m_SerialNumber = id; }
|
||||
|
||||
std::map<std::string, Timer>& GetTimers() { return m_timers; }
|
||||
void SetTimer(std::string name, uint32 time);
|
||||
void StopTimer(std::string name);
|
||||
void ClearTimers();
|
||||
|
||||
// Get a total of a stat, including augs
|
||||
// These functions should be used in place of other code manually totaling
|
||||
// to centralize where it is done to make future changes easier (ex. whenever powersources come around)
|
||||
// and to minimize errors. CalcItemBonuses however doesn't use these in interest of performance
|
||||
// by default these do not recurse into augs
|
||||
int GetItemArmorClass(bool augments = false) const;
|
||||
int GetItemElementalDamage(int &magic, int &fire, int &cold, int &poison, int &disease, int &chromatic, int &prismatic, int &physical, int &corruption, bool augments = false) const;
|
||||
// These two differ in the fact that they're quick checks (they are checked BEFORE the one above
|
||||
int GetItemElementalFlag(bool augments = false) const;
|
||||
int GetItemElementalDamage(bool augments = false) const;
|
||||
int GetItemRecommendedLevel(bool augments = false) const;
|
||||
int GetItemRequiredLevel(bool augments = false) const;
|
||||
int GetItemWeaponDamage(bool augments = false) const;
|
||||
int GetItemBackstabDamage(bool augments = false) const;
|
||||
// these two are just quick checks
|
||||
int GetItemBaneDamageBody(bool augments = false) const;
|
||||
int GetItemBaneDamageRace(bool augments = false) const;
|
||||
int GetItemBaneDamageBody(bodyType against, bool augments = false) const;
|
||||
int GetItemBaneDamageRace(uint16 against, bool augments = false) const;
|
||||
int GetItemMagical(bool augments = false) const;
|
||||
int GetItemHP(bool augments = false) const;
|
||||
int GetItemMana(bool augments = false) const;
|
||||
int GetItemEndur(bool augments = false) const;
|
||||
int GetItemAttack(bool augments = false) const;
|
||||
int GetItemStr(bool augments = false) const;
|
||||
int GetItemSta(bool augments = false) const;
|
||||
int GetItemDex(bool augments = false) const;
|
||||
int GetItemAgi(bool augments = false) const;
|
||||
int GetItemInt(bool augments = false) const;
|
||||
int GetItemWis(bool augments = false) const;
|
||||
int GetItemCha(bool augments = false) const;
|
||||
int GetItemMR(bool augments = false) const;
|
||||
int GetItemFR(bool augments = false) const;
|
||||
int GetItemCR(bool augments = false) const;
|
||||
int GetItemPR(bool augments = false) const;
|
||||
int GetItemDR(bool augments = false) const;
|
||||
int GetItemCorrup(bool augments = false) const;
|
||||
int GetItemHeroicStr(bool augments = false) const;
|
||||
int GetItemHeroicSta(bool augments = false) const;
|
||||
int GetItemHeroicDex(bool augments = false) const;
|
||||
int GetItemHeroicAgi(bool augments = false) const;
|
||||
int GetItemHeroicInt(bool augments = false) const;
|
||||
int GetItemHeroicWis(bool augments = false) const;
|
||||
int GetItemHeroicCha(bool augments = false) const;
|
||||
int GetItemHeroicMR(bool augments = false) const;
|
||||
int GetItemHeroicFR(bool augments = false) const;
|
||||
int GetItemHeroicCR(bool augments = false) const;
|
||||
int GetItemHeroicPR(bool augments = false) const;
|
||||
int GetItemHeroicDR(bool augments = false) const;
|
||||
int GetItemHeroicCorrup(bool augments = false) const;
|
||||
int GetItemHaste(bool augments = false) const;
|
||||
|
||||
protected:
|
||||
//////////////////////////
|
||||
// Protected Members
|
||||
//////////////////////////
|
||||
friend class InventoryProfile;
|
||||
|
||||
std::map<uint8, ItemInstance*>::const_iterator _cbegin() { return m_contents.cbegin(); }
|
||||
std::map<uint8, ItemInstance*>::const_iterator _cend() { return m_contents.cend(); }
|
||||
|
||||
void _PutItem(uint8 index, ItemInstance* inst) { m_contents[index] = inst; }
|
||||
|
||||
ItemInstTypes m_use_type; // Usage type for item
|
||||
const ItemData* m_item; // Ptr to item data
|
||||
int16 m_charges; // # of charges for chargeable items
|
||||
uint32 m_price; // Bazaar /trader price
|
||||
uint32 m_color;
|
||||
uint32 m_merchantslot;
|
||||
int16 m_currentslot;
|
||||
bool m_attuned;
|
||||
int32 m_merchantcount; //number avaliable on the merchant, -1=unlimited
|
||||
int32 m_SerialNumber; // Unique identifier for this instance of an item. Needed for Bazaar.
|
||||
uint32 m_exp;
|
||||
int8 m_evolveLvl;
|
||||
bool m_activated;
|
||||
ItemData* m_scaledItem;
|
||||
::EvolveInfo* m_evolveInfo;
|
||||
bool m_scaling;
|
||||
uint32 m_ornamenticon;
|
||||
uint32 m_ornamentidfile;
|
||||
uint32 m_ornament_hero_model;
|
||||
uint32 m_recast_timestamp;
|
||||
|
||||
//
|
||||
// Items inside of this item (augs or contents);
|
||||
std::map<uint8, ItemInstance*> m_contents; // Zero-based index: min=0, max=9
|
||||
std::map<std::string, std::string> m_custom_data;
|
||||
std::map<std::string, Timer> m_timers;
|
||||
};
|
||||
}
|
||||
|
||||
class EvolveInfo {
|
||||
public:
|
||||
friend class EQEmu::ItemInstance;
|
||||
//temporary
|
||||
uint16 LvlKills[9];
|
||||
uint32 FirstItem;
|
||||
uint8 MaxLvl;
|
||||
bool AllKills;
|
||||
|
||||
EvolveInfo();
|
||||
EvolveInfo(uint32 first, uint8 max, bool allkills, uint32 L2, uint32 L3, uint32 L4, uint32 L5, uint32 L6, uint32 L7, uint32 L8, uint32 L9, uint32 L10);
|
||||
~EvolveInfo();
|
||||
};
|
||||
|
||||
#endif /*COMMON_ITEM_INSTANCE_H*/
|
||||
+95
-100
@@ -29,7 +29,7 @@
|
||||
#include "../eq_packet_structs.h"
|
||||
#include "../misc_functions.h"
|
||||
#include "../string_util.h"
|
||||
#include "../inventory_profile.h"
|
||||
#include "../item.h"
|
||||
#include "rof_structs.h"
|
||||
#include "../rulesys.h"
|
||||
|
||||
@@ -45,7 +45,7 @@ namespace RoF
|
||||
static OpcodeManager *opcodes = nullptr;
|
||||
static Strategy struct_strategy;
|
||||
|
||||
void SerializeItem(EQEmu::OutBuffer& ob, const EQEmu::ItemInstance *inst, int16 slot_id, uint8 depth);
|
||||
void SerializeItem(EQEmu::OutBuffer& ob, const ItemInst *inst, int16 slot_id, uint8 depth);
|
||||
|
||||
// server to client inventory location converters
|
||||
static inline structs::InventorySlot_Struct ServerToRoFSlot(uint32 serverSlot);
|
||||
@@ -66,9 +66,6 @@ namespace RoF
|
||||
static inline CastingSlot ServerToRoFCastingSlot(EQEmu::CastingSlot slot);
|
||||
static inline EQEmu::CastingSlot RoFToServerCastingSlot(CastingSlot slot);
|
||||
|
||||
static inline int ServerToRoFBuffSlot(int index);
|
||||
static inline int RoFToServerBuffSlot(int index);
|
||||
|
||||
void Register(EQStreamIdentifier &into)
|
||||
{
|
||||
//create our opcode manager if we havent already
|
||||
@@ -426,8 +423,15 @@ namespace RoF
|
||||
OUT(buff.y);
|
||||
OUT(buff.x);
|
||||
OUT(buff.z);
|
||||
uint16 buffslot = emu->slotid;
|
||||
// Not sure if this is needs amending for RoF yet.
|
||||
if (buffslot >= 25)
|
||||
{
|
||||
buffslot += 17;
|
||||
}
|
||||
|
||||
// TODO: implement slot_data stuff
|
||||
eq->slotid = ServerToRoFBuffSlot(emu->slotid);
|
||||
eq->slotid = buffslot;
|
||||
|
||||
if (emu->bufffade == 1)
|
||||
eq->bufffade = 1;
|
||||
@@ -443,10 +447,10 @@ namespace RoF
|
||||
outapp->WriteUInt32(0); // tic timer
|
||||
outapp->WriteUInt8(0); // Type of OP_BuffCreate packet ?
|
||||
outapp->WriteUInt16(1); // 1 buff in this packet
|
||||
outapp->WriteUInt32(eq->slotid);
|
||||
outapp->WriteUInt32(buffslot);
|
||||
outapp->WriteUInt32(0xffffffff); // SpellID (0xffff to remove)
|
||||
outapp->WriteUInt32(0); // Duration
|
||||
outapp->WriteUInt32(0); // numhits
|
||||
outapp->WriteUInt32(0); // ?
|
||||
outapp->WriteUInt8(0); // Caster name
|
||||
outapp->WriteUInt8(0); // Type
|
||||
}
|
||||
@@ -470,9 +474,16 @@ namespace RoF
|
||||
__packet->WriteUInt8(emu->all_buffs); // 1 indicates all buffs on the player (0 to add or remove a single buff)
|
||||
__packet->WriteUInt16(emu->count);
|
||||
|
||||
for (int i = 0; i < emu->count; ++i)
|
||||
for (uint16 i = 0; i < emu->count; ++i)
|
||||
{
|
||||
__packet->WriteUInt32(emu->type == 0 ? ServerToRoFBuffSlot(emu->entries[i].buff_slot) : emu->entries[i].buff_slot);
|
||||
uint16 buffslot = emu->entries[i].buff_slot;
|
||||
// Not sure if this is needs amending for RoF yet.
|
||||
if (emu->entries[i].buff_slot >= 25)
|
||||
{
|
||||
buffslot += 17;
|
||||
}
|
||||
|
||||
__packet->WriteUInt32(buffslot);
|
||||
__packet->WriteUInt32(emu->entries[i].spell_id);
|
||||
__packet->WriteUInt32(emu->entries[i].tics_remaining);
|
||||
__packet->WriteUInt32(emu->entries[i].num_hits); // Unknown
|
||||
@@ -584,7 +595,7 @@ namespace RoF
|
||||
ob.write((const char*)&item_count, sizeof(uint32));
|
||||
|
||||
for (int index = 0; index < item_count; ++index, ++eq) {
|
||||
SerializeItem(ob, (const EQEmu::ItemInstance*)eq->inst, eq->slot_id, 0);
|
||||
SerializeItem(ob, (const ItemInst*)eq->inst, eq->slot_id, 0);
|
||||
if (ob.tellp() == last_pos)
|
||||
Log.Out(Logs::General, Logs::Netcode, "[STRUCTS] Serialization failed on item slot %d during OP_CharInventory. Item skipped.", eq->slot_id);
|
||||
|
||||
@@ -975,8 +986,8 @@ namespace RoF
|
||||
VARSTRUCT_ENCODE_TYPE(uint32, OutBuffer, emu->drop_id); // Some unique id
|
||||
VARSTRUCT_ENCODE_TYPE(uint32, OutBuffer, 0); // Same for all objects in the zone
|
||||
VARSTRUCT_ENCODE_TYPE(float, OutBuffer, emu->heading);
|
||||
VARSTRUCT_ENCODE_TYPE(float, OutBuffer, emu->tilt_x); // X tilt
|
||||
VARSTRUCT_ENCODE_TYPE(float, OutBuffer, emu->tilt_y); // Y tilt
|
||||
VARSTRUCT_ENCODE_TYPE(float, OutBuffer, 0); // X tilt
|
||||
VARSTRUCT_ENCODE_TYPE(float, OutBuffer, 0); // Y tilt
|
||||
VARSTRUCT_ENCODE_TYPE(float, OutBuffer, emu->size != 0 && (float)emu->size < 5000.f ? (float)((float)emu->size / 100.0f) : 1.f ); // This appears to be the size field. Hackish logic because some PEQ DB items were corrupt.
|
||||
VARSTRUCT_ENCODE_TYPE(float, OutBuffer, emu->y);
|
||||
VARSTRUCT_ENCODE_TYPE(float, OutBuffer, emu->x);
|
||||
@@ -1492,6 +1503,17 @@ namespace RoF
|
||||
FINISH_ENCODE();
|
||||
}
|
||||
|
||||
ENCODE(OP_InterruptCast)
|
||||
{
|
||||
ENCODE_LENGTH_EXACT(InterruptCast_Struct);
|
||||
SETUP_DIRECT_ENCODE(InterruptCast_Struct, structs::InterruptCast_Struct);
|
||||
|
||||
OUT(spawnid);
|
||||
OUT(messageid);
|
||||
|
||||
FINISH_ENCODE();
|
||||
}
|
||||
|
||||
ENCODE(OP_ItemLinkResponse) { ENCODE_FORWARD(OP_ItemPacket); }
|
||||
|
||||
ENCODE(OP_ItemPacket)
|
||||
@@ -1510,7 +1532,7 @@ namespace RoF
|
||||
|
||||
ob.write((const char*)__emu_buffer, 4);
|
||||
|
||||
SerializeItem(ob, (const EQEmu::ItemInstance*)int_struct->inst, int_struct->slot_id, 0);
|
||||
SerializeItem(ob, (const ItemInst*)int_struct->inst, int_struct->slot_id, 0);
|
||||
if (ob.tellp() == last_pos) {
|
||||
Log.Out(Logs::General, Logs::Netcode, "[STRUCTS] Serialization failed on item slot %d.", int_struct->slot_id);
|
||||
delete in;
|
||||
@@ -2056,7 +2078,7 @@ namespace RoF
|
||||
|
||||
outapp->WriteUInt32(22); // Equipment count
|
||||
|
||||
for (int r = EQEmu::textures::textureBegin; r < EQEmu::textures::materialCount; r++)
|
||||
for (int r = EQEmu::textures::TextureBegin; r < EQEmu::textures::TextureCount; r++)
|
||||
{
|
||||
outapp->WriteUInt32(emu->item_material.Slot[r].Material);
|
||||
outapp->WriteUInt32(0);
|
||||
@@ -2076,9 +2098,9 @@ namespace RoF
|
||||
outapp->WriteUInt32(0);
|
||||
}
|
||||
|
||||
outapp->WriteUInt32(EQEmu::textures::materialCount); // Equipment2 count
|
||||
outapp->WriteUInt32(EQEmu::textures::TextureCount); // Equipment2 count
|
||||
|
||||
for (int r = EQEmu::textures::textureBegin; r < EQEmu::textures::materialCount; r++)
|
||||
for (int r = EQEmu::textures::TextureBegin; r < EQEmu::textures::TextureCount; r++)
|
||||
{
|
||||
outapp->WriteUInt32(0);
|
||||
outapp->WriteUInt32(0);
|
||||
@@ -2087,7 +2109,7 @@ namespace RoF
|
||||
outapp->WriteUInt32(0);
|
||||
}
|
||||
|
||||
outapp->WriteUInt32(EQEmu::textures::materialCount); // Tint Count
|
||||
outapp->WriteUInt32(EQEmu::textures::TextureCount); // Tint Count
|
||||
|
||||
for (int r = 0; r < 7; r++)
|
||||
{
|
||||
@@ -2097,7 +2119,7 @@ namespace RoF
|
||||
outapp->WriteUInt32(0);
|
||||
outapp->WriteUInt32(0);
|
||||
|
||||
outapp->WriteUInt32(EQEmu::textures::materialCount); // Tint2 Count
|
||||
outapp->WriteUInt32(EQEmu::textures::TextureCount); // Tint2 Count
|
||||
|
||||
for (int r = 0; r < 7; r++)
|
||||
{
|
||||
@@ -3036,12 +3058,12 @@ namespace RoF
|
||||
eq_cse->Gender = emu_cse->Gender;
|
||||
eq_cse->Face = emu_cse->Face;
|
||||
|
||||
for (int equip_index = 0; equip_index < EQEmu::textures::materialCount; equip_index++) {
|
||||
for (int equip_index = 0; equip_index < EQEmu::textures::TextureCount; equip_index++) {
|
||||
eq_cse->Equip[equip_index].Material = emu_cse->Equip[equip_index].Material;
|
||||
eq_cse->Equip[equip_index].Unknown1 = emu_cse->Equip[equip_index].Unknown1;
|
||||
eq_cse->Equip[equip_index].EliteMaterial = emu_cse->Equip[equip_index].EliteModel;
|
||||
eq_cse->Equip[equip_index].HeroForgeModel = emu_cse->Equip[equip_index].HerosForgeModel;
|
||||
eq_cse->Equip[equip_index].Material2 = emu_cse->Equip[equip_index].Unknown2;
|
||||
eq_cse->Equip[equip_index].EliteMaterial = emu_cse->Equip[equip_index].EliteMaterial;
|
||||
eq_cse->Equip[equip_index].HeroForgeModel = emu_cse->Equip[equip_index].HeroForgeModel;
|
||||
eq_cse->Equip[equip_index].Material2 = emu_cse->Equip[equip_index].Material2;
|
||||
eq_cse->Equip[equip_index].Color = emu_cse->Equip[equip_index].Color;
|
||||
}
|
||||
|
||||
@@ -4073,7 +4095,7 @@ namespace RoF
|
||||
|
||||
if ((emu->NPC == 0) || (emu->race <= 12) || (emu->race == 128) || (emu->race == 130) || (emu->race == 330) || (emu->race == 522))
|
||||
{
|
||||
for (k = EQEmu::textures::textureBegin; k < EQEmu::textures::materialCount; ++k)
|
||||
for (k = EQEmu::textures::TextureBegin; k < EQEmu::textures::TextureCount; ++k)
|
||||
{
|
||||
{
|
||||
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, emu->equipment_tint.Slot[k].Color);
|
||||
@@ -4082,15 +4104,15 @@ namespace RoF
|
||||
|
||||
structs::Texture_Struct *Equipment = (structs::Texture_Struct *)Buffer;
|
||||
|
||||
for (k = EQEmu::textures::textureBegin; k < EQEmu::textures::materialCount; k++) {
|
||||
for (k = EQEmu::textures::TextureBegin; k < EQEmu::textures::TextureCount; k++) {
|
||||
Equipment[k].Material = emu->equipment.Slot[k].Material;
|
||||
Equipment[k].Unknown1 = emu->equipment.Slot[k].Unknown1;
|
||||
Equipment[k].EliteMaterial = emu->equipment.Slot[k].EliteModel;
|
||||
Equipment[k].HeroForgeModel = emu->equipment.Slot[k].HerosForgeModel;
|
||||
Equipment[k].Material2 = emu->equipment.Slot[k].Unknown2;
|
||||
Equipment[k].EliteMaterial = emu->equipment.Slot[k].EliteMaterial;
|
||||
Equipment[k].HeroForgeModel = emu->equipment.Slot[k].HeroForgeModel;
|
||||
Equipment[k].Material2 = emu->equipment.Slot[k].Material2;
|
||||
}
|
||||
|
||||
Buffer += (sizeof(structs::Texture_Struct) * EQEmu::textures::materialCount);
|
||||
Buffer += (sizeof(structs::Texture_Struct) * EQEmu::textures::TextureCount);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -4289,7 +4311,7 @@ namespace RoF
|
||||
IN(buff.unknown003);
|
||||
IN(buff.spellid);
|
||||
IN(buff.duration);
|
||||
emu->slotid = RoFToServerBuffSlot(eq->slotid);
|
||||
IN(slotid);
|
||||
IN(bufffade);
|
||||
|
||||
FINISH_DIRECT_DECODE();
|
||||
@@ -4302,7 +4324,7 @@ namespace RoF
|
||||
DECODE_LENGTH_EXACT(structs::BuffRemoveRequest_Struct);
|
||||
SETUP_DIRECT_DECODE(BuffRemoveRequest_Struct, structs::BuffRemoveRequest_Struct);
|
||||
|
||||
emu->SlotID = RoFToServerBuffSlot(eq->SlotID);
|
||||
emu->SlotID = (eq->SlotID < 42) ? eq->SlotID : (eq->SlotID - 17);
|
||||
|
||||
IN(EntityID);
|
||||
|
||||
@@ -4806,9 +4828,10 @@ namespace RoF
|
||||
|
||||
IN(item_id);
|
||||
int r;
|
||||
for (r = EQEmu::inventory::socketBegin; r < EQEmu::inventory::SocketCount; r++) {
|
||||
for (r = 0; r < EQEmu::legacy::ITEM_COMMON_SIZE; r++) {
|
||||
IN(augments[r]);
|
||||
}
|
||||
// Max Augs is now 6, but no code to support that many yet
|
||||
IN(link_hash);
|
||||
IN(icon);
|
||||
|
||||
@@ -5185,9 +5208,9 @@ namespace RoF
|
||||
return NextItemInstSerialNumber;
|
||||
}
|
||||
|
||||
void SerializeItem(EQEmu::OutBuffer& ob, const EQEmu::ItemInstance *inst, int16 slot_id_in, uint8 depth)
|
||||
void SerializeItem(EQEmu::OutBuffer& ob, const ItemInst *inst, int16 slot_id_in, uint8 depth)
|
||||
{
|
||||
const EQEmu::ItemData *item = inst->GetUnscaledItem();
|
||||
const EQEmu::ItemBase *item = inst->GetUnscaledItem();
|
||||
|
||||
RoF::structs::ItemSerializationHeader hdr;
|
||||
|
||||
@@ -5241,7 +5264,7 @@ namespace RoF
|
||||
|
||||
if (inst->GetOrnamentationIDFile() && inst->GetOrnamentationIcon()) {
|
||||
ornaIcon = inst->GetOrnamentationIcon();
|
||||
heroModel = inst->GetOrnamentHeroModel(EQEmu::InventoryProfile::CalcMaterialFromSlot(slot_id_in));
|
||||
heroModel = inst->GetOrnamentHeroModel(Inventory::CalcMaterialFromSlot(slot_id_in));
|
||||
|
||||
char tmp[30]; memset(tmp, 0x0, 30); sprintf(tmp, "IT%d", inst->GetOrnamentationIDFile());
|
||||
|
||||
@@ -5598,18 +5621,18 @@ namespace RoF
|
||||
|
||||
ob.write((const char*)&subitem_count, sizeof(uint32));
|
||||
|
||||
for (uint32 index = EQEmu::inventory::containerBegin; index < EQEmu::inventory::ContainerCount; ++index) {
|
||||
EQEmu::ItemInstance* sub = inst->GetItem(index);
|
||||
for (uint32 index = SUB_INDEX_BEGIN; index < EQEmu::legacy::ITEM_CONTAINER_SIZE; ++index) {
|
||||
ItemInst* sub = inst->GetItem(index);
|
||||
if (!sub)
|
||||
continue;
|
||||
|
||||
int SubSlotNumber = INVALID_INDEX;
|
||||
if (slot_id_in >= EQEmu::legacy::GENERAL_BEGIN && slot_id_in <= EQEmu::legacy::GENERAL_END)
|
||||
SubSlotNumber = (((slot_id_in + 3) * EQEmu::inventory::ContainerCount) + index + 1);
|
||||
SubSlotNumber = (((slot_id_in + 3) * EQEmu::legacy::ITEM_CONTAINER_SIZE) + index + 1);
|
||||
else if (slot_id_in >= EQEmu::legacy::BANK_BEGIN && slot_id_in <= EQEmu::legacy::BANK_END)
|
||||
SubSlotNumber = (((slot_id_in - EQEmu::legacy::BANK_BEGIN) * EQEmu::inventory::ContainerCount) + EQEmu::legacy::BANK_BAGS_BEGIN + index);
|
||||
SubSlotNumber = (((slot_id_in - EQEmu::legacy::BANK_BEGIN) * EQEmu::legacy::ITEM_CONTAINER_SIZE) + EQEmu::legacy::BANK_BAGS_BEGIN + index);
|
||||
else if (slot_id_in >= EQEmu::legacy::SHARED_BANK_BEGIN && slot_id_in <= EQEmu::legacy::SHARED_BANK_END)
|
||||
SubSlotNumber = (((slot_id_in - EQEmu::legacy::SHARED_BANK_BEGIN) * EQEmu::inventory::ContainerCount) + EQEmu::legacy::SHARED_BANK_BAGS_BEGIN + index);
|
||||
SubSlotNumber = (((slot_id_in - EQEmu::legacy::SHARED_BANK_BEGIN) * EQEmu::legacy::ITEM_CONTAINER_SIZE) + EQEmu::legacy::SHARED_BANK_BAGS_BEGIN + index);
|
||||
else
|
||||
SubSlotNumber = slot_id_in;
|
||||
|
||||
@@ -5635,17 +5658,17 @@ namespace RoF
|
||||
|
||||
uint32 TempSlot = 0;
|
||||
|
||||
if (serverSlot < 56 || serverSlot == EQEmu::inventory::slotPowerSource) { // Main Inventory and Cursor
|
||||
if (serverSlot < 56 || serverSlot == EQEmu::legacy::SlotPowerSource) { // Main Inventory and Cursor
|
||||
RoFSlot.Type = invtype::InvTypePossessions;
|
||||
RoFSlot.Slot = serverSlot;
|
||||
|
||||
if (serverSlot == EQEmu::inventory::slotPowerSource)
|
||||
if (serverSlot == EQEmu::legacy::SlotPowerSource)
|
||||
RoFSlot.Slot = invslot::PossessionsPowerSource;
|
||||
|
||||
else if (serverSlot >= EQEmu::inventory::slotCursor) // Cursor and Extended Corpse Inventory
|
||||
else if (serverSlot >= EQEmu::legacy::SlotCursor) // Cursor and Extended Corpse Inventory
|
||||
RoFSlot.Slot += 3;
|
||||
|
||||
else if (serverSlot >= EQEmu::inventory::slotAmmo) // (> 20)
|
||||
else if (serverSlot >= EQEmu::legacy::SlotAmmo) // (> 20)
|
||||
RoFSlot.Slot += 1;
|
||||
}
|
||||
|
||||
@@ -5657,8 +5680,8 @@ namespace RoF
|
||||
else if (serverSlot >= EQEmu::legacy::GENERAL_BAGS_BEGIN && serverSlot <= EQEmu::legacy::CURSOR_BAG_END) { // (> 250 && < 341)
|
||||
RoFSlot.Type = invtype::InvTypePossessions;
|
||||
TempSlot = serverSlot - 1;
|
||||
RoFSlot.Slot = int(TempSlot / EQEmu::inventory::ContainerCount) - 2;
|
||||
RoFSlot.SubIndex = TempSlot - ((RoFSlot.Slot + 2) * EQEmu::inventory::ContainerCount);
|
||||
RoFSlot.Slot = int(TempSlot / EQEmu::legacy::ITEM_CONTAINER_SIZE) - 2;
|
||||
RoFSlot.SubIndex = TempSlot - ((RoFSlot.Slot + 2) * EQEmu::legacy::ITEM_CONTAINER_SIZE);
|
||||
|
||||
if (RoFSlot.Slot >= invslot::PossessionsGeneral9) // (> 30)
|
||||
RoFSlot.Slot = invslot::PossessionsCursor;
|
||||
@@ -5675,8 +5698,8 @@ namespace RoF
|
||||
RoFSlot.Slot = TempSlot;
|
||||
|
||||
if (TempSlot > 30) { // (> 30)
|
||||
RoFSlot.Slot = int(TempSlot / EQEmu::inventory::ContainerCount) - 3;
|
||||
RoFSlot.SubIndex = TempSlot - ((RoFSlot.Slot + 3) * EQEmu::inventory::ContainerCount);
|
||||
RoFSlot.Slot = int(TempSlot / EQEmu::legacy::ITEM_CONTAINER_SIZE) - 3;
|
||||
RoFSlot.SubIndex = TempSlot - ((RoFSlot.Slot + 3) * EQEmu::legacy::ITEM_CONTAINER_SIZE);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5686,8 +5709,8 @@ namespace RoF
|
||||
RoFSlot.Slot = TempSlot;
|
||||
|
||||
if (TempSlot > 30) { // (> 30)
|
||||
RoFSlot.Slot = int(TempSlot / EQEmu::inventory::ContainerCount) - 3;
|
||||
RoFSlot.SubIndex = TempSlot - ((RoFSlot.Slot + 3) * EQEmu::inventory::ContainerCount);
|
||||
RoFSlot.Slot = int(TempSlot / EQEmu::legacy::ITEM_CONTAINER_SIZE) - 3;
|
||||
RoFSlot.SubIndex = TempSlot - ((RoFSlot.Slot + 3) * EQEmu::legacy::ITEM_CONTAINER_SIZE);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5697,8 +5720,8 @@ namespace RoF
|
||||
RoFSlot.Slot = TempSlot;
|
||||
|
||||
if (TempSlot > 30) {
|
||||
RoFSlot.Slot = int(TempSlot / EQEmu::inventory::ContainerCount) - 3;
|
||||
RoFSlot.SubIndex = TempSlot - ((RoFSlot.Slot + 3) * EQEmu::inventory::ContainerCount);
|
||||
RoFSlot.Slot = int(TempSlot / EQEmu::legacy::ITEM_CONTAINER_SIZE) - 3;
|
||||
RoFSlot.SubIndex = TempSlot - ((RoFSlot.Slot + 3) * EQEmu::legacy::ITEM_CONTAINER_SIZE);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -5736,16 +5759,16 @@ namespace RoF
|
||||
|
||||
uint32 TempSlot = 0;
|
||||
|
||||
if (serverSlot < 56 || serverSlot == EQEmu::inventory::slotPowerSource) { // (< 52)
|
||||
if (serverSlot < 56 || serverSlot == EQEmu::legacy::SlotPowerSource) { // (< 52)
|
||||
RoFSlot.Slot = serverSlot;
|
||||
|
||||
if (serverSlot == EQEmu::inventory::slotPowerSource)
|
||||
if (serverSlot == EQEmu::legacy::SlotPowerSource)
|
||||
RoFSlot.Slot = invslot::PossessionsPowerSource;
|
||||
|
||||
else if (serverSlot >= EQEmu::inventory::slotCursor) // Cursor and Extended Corpse Inventory
|
||||
else if (serverSlot >= EQEmu::legacy::SlotCursor) // Cursor and Extended Corpse Inventory
|
||||
RoFSlot.Slot += 3;
|
||||
|
||||
else if (serverSlot >= EQEmu::inventory::slotAmmo) // Ammo and Personl Inventory
|
||||
else if (serverSlot >= EQEmu::legacy::SlotAmmo) // Ammo and Personl Inventory
|
||||
RoFSlot.Slot += 1;
|
||||
|
||||
/*else if (ServerSlot >= MainCursor) { // Cursor
|
||||
@@ -5758,8 +5781,8 @@ namespace RoF
|
||||
|
||||
else if (serverSlot >= EQEmu::legacy::GENERAL_BAGS_BEGIN && serverSlot <= EQEmu::legacy::CURSOR_BAG_END) {
|
||||
TempSlot = serverSlot - 1;
|
||||
RoFSlot.Slot = int(TempSlot / EQEmu::inventory::ContainerCount) - 2;
|
||||
RoFSlot.SubIndex = TempSlot - ((RoFSlot.Slot + 2) * EQEmu::inventory::ContainerCount);
|
||||
RoFSlot.Slot = int(TempSlot / EQEmu::legacy::ITEM_CONTAINER_SIZE) - 2;
|
||||
RoFSlot.SubIndex = TempSlot - ((RoFSlot.Slot + 2) * EQEmu::legacy::ITEM_CONTAINER_SIZE);
|
||||
}
|
||||
|
||||
Log.Out(Logs::General, Logs::Netcode, "[ERROR] Convert Server Slot %i to RoF Slots: Main %i, Sub %i, Aug %i, Unk1 %i", serverSlot, RoFSlot.Slot, RoFSlot.SubIndex, RoFSlot.AugIndex, RoFSlot.Unknown01);
|
||||
@@ -5779,7 +5802,7 @@ namespace RoF
|
||||
|
||||
if (rofSlot.Type == invtype::InvTypePossessions && rofSlot.Slot < 57) { // Worn/Personal Inventory and Cursor (< 51)
|
||||
if (rofSlot.Slot == invslot::PossessionsPowerSource)
|
||||
TempSlot = EQEmu::inventory::slotPowerSource;
|
||||
TempSlot = EQEmu::legacy::SlotPowerSource;
|
||||
|
||||
else if (rofSlot.Slot >= invslot::PossessionsCursor) // Cursor and Extended Corpse Inventory
|
||||
TempSlot = rofSlot.Slot - 3;
|
||||
@@ -5801,8 +5824,8 @@ namespace RoF
|
||||
else // Worn Slots
|
||||
TempSlot = rofSlot.Slot;
|
||||
|
||||
if (rofSlot.SubIndex >= EQEmu::inventory::containerBegin) // Bag Slots
|
||||
TempSlot = ((TempSlot + 3) * EQEmu::inventory::ContainerCount) + rofSlot.SubIndex + 1;
|
||||
if (rofSlot.SubIndex >= SUB_INDEX_BEGIN) // Bag Slots
|
||||
TempSlot = ((TempSlot + 3) * EQEmu::legacy::ITEM_CONTAINER_SIZE) + rofSlot.SubIndex + 1;
|
||||
|
||||
ServerSlot = TempSlot;
|
||||
}
|
||||
@@ -5810,8 +5833,8 @@ namespace RoF
|
||||
else if (rofSlot.Type == invtype::InvTypeBank) {
|
||||
TempSlot = EQEmu::legacy::BANK_BEGIN;
|
||||
|
||||
if (rofSlot.SubIndex >= EQEmu::inventory::containerBegin)
|
||||
TempSlot += ((rofSlot.Slot + 3) * EQEmu::inventory::ContainerCount) + rofSlot.SubIndex + 1;
|
||||
if (rofSlot.SubIndex >= SUB_INDEX_BEGIN)
|
||||
TempSlot += ((rofSlot.Slot + 3) * EQEmu::legacy::ITEM_CONTAINER_SIZE) + rofSlot.SubIndex + 1;
|
||||
|
||||
else
|
||||
TempSlot += rofSlot.Slot;
|
||||
@@ -5822,8 +5845,8 @@ namespace RoF
|
||||
else if (rofSlot.Type == invtype::InvTypeSharedBank) {
|
||||
TempSlot = EQEmu::legacy::SHARED_BANK_BEGIN;
|
||||
|
||||
if (rofSlot.SubIndex >= EQEmu::inventory::containerBegin)
|
||||
TempSlot += ((rofSlot.Slot + 3) * EQEmu::inventory::ContainerCount) + rofSlot.SubIndex + 1;
|
||||
if (rofSlot.SubIndex >= SUB_INDEX_BEGIN)
|
||||
TempSlot += ((rofSlot.Slot + 3) * EQEmu::legacy::ITEM_CONTAINER_SIZE) + rofSlot.SubIndex + 1;
|
||||
|
||||
else
|
||||
TempSlot += rofSlot.Slot;
|
||||
@@ -5834,10 +5857,10 @@ namespace RoF
|
||||
else if (rofSlot.Type == invtype::InvTypeTrade) {
|
||||
TempSlot = EQEmu::legacy::TRADE_BEGIN;
|
||||
|
||||
if (rofSlot.SubIndex >= EQEmu::inventory::containerBegin)
|
||||
TempSlot += ((rofSlot.Slot + 3) * EQEmu::inventory::ContainerCount) + rofSlot.SubIndex + 1;
|
||||
if (rofSlot.SubIndex >= SUB_INDEX_BEGIN)
|
||||
TempSlot += ((rofSlot.Slot + 3) * EQEmu::legacy::ITEM_CONTAINER_SIZE) + rofSlot.SubIndex + 1;
|
||||
// OLD CODE:
|
||||
//TempSlot += 100 + (RoFSlot.MainSlot * EQEmu::inventory::ContainerCount) + RoFSlot.SubSlot;
|
||||
//TempSlot += 100 + (RoFSlot.MainSlot * EQEmu::legacy::ITEM_CONTAINER_SIZE) + RoFSlot.SubSlot;
|
||||
|
||||
else
|
||||
TempSlot += rofSlot.Slot;
|
||||
@@ -5848,7 +5871,7 @@ namespace RoF
|
||||
else if (rofSlot.Type == invtype::InvTypeWorld) {
|
||||
TempSlot = EQEmu::legacy::WORLD_BEGIN;
|
||||
|
||||
if (rofSlot.Slot >= EQEmu::inventory::containerBegin)
|
||||
if (rofSlot.Slot >= SUB_INDEX_BEGIN)
|
||||
TempSlot += rofSlot.Slot;
|
||||
|
||||
ServerSlot = TempSlot;
|
||||
@@ -5879,7 +5902,7 @@ namespace RoF
|
||||
|
||||
if (rofSlot.Slot < 57) { // Worn/Personal Inventory and Cursor (< 33)
|
||||
if (rofSlot.Slot == invslot::PossessionsPowerSource)
|
||||
TempSlot = EQEmu::inventory::slotPowerSource;
|
||||
TempSlot = EQEmu::legacy::SlotPowerSource;
|
||||
|
||||
else if (rofSlot.Slot >= invslot::PossessionsCursor) // Cursor and Extended Corpse Inventory
|
||||
TempSlot = rofSlot.Slot - 3;
|
||||
@@ -5896,8 +5919,8 @@ namespace RoF
|
||||
else
|
||||
TempSlot = rofSlot.Slot;
|
||||
|
||||
if (rofSlot.SubIndex >= EQEmu::inventory::containerBegin) // Bag Slots
|
||||
TempSlot = ((TempSlot + 3) * EQEmu::inventory::ContainerCount) + rofSlot.SubIndex + 1;
|
||||
if (rofSlot.SubIndex >= SUB_INDEX_BEGIN) // Bag Slots
|
||||
TempSlot = ((TempSlot + 3) * EQEmu::legacy::ITEM_CONTAINER_SIZE) + rofSlot.SubIndex + 1;
|
||||
|
||||
ServerSlot = TempSlot;
|
||||
}
|
||||
@@ -6061,32 +6084,4 @@ namespace RoF
|
||||
return EQEmu::CastingSlot::Discipline;
|
||||
}
|
||||
}
|
||||
|
||||
// these should be optimized out for RoF since they should all boil down to return index :P
|
||||
// but lets leave it here for future proofing
|
||||
static inline int ServerToRoFBuffSlot(int index)
|
||||
{
|
||||
// we're a disc
|
||||
if (index >= EQEmu::constants::LongBuffs + EQEmu::constants::ShortBuffs)
|
||||
return index - EQEmu::constants::LongBuffs - EQEmu::constants::ShortBuffs +
|
||||
constants::LongBuffs + constants::ShortBuffs;
|
||||
// we're a song
|
||||
if (index >= EQEmu::constants::LongBuffs)
|
||||
return index - EQEmu::constants::LongBuffs + constants::LongBuffs;
|
||||
// we're a normal buff
|
||||
return index; // as long as we guard against bad slots server side, we should be fine
|
||||
}
|
||||
|
||||
static inline int RoFToServerBuffSlot(int index)
|
||||
{
|
||||
// we're a disc
|
||||
if (index >= constants::LongBuffs + constants::ShortBuffs)
|
||||
return index - constants::LongBuffs - constants::ShortBuffs + EQEmu::constants::LongBuffs +
|
||||
EQEmu::constants::ShortBuffs;
|
||||
// we're a song
|
||||
if (index >= constants::LongBuffs)
|
||||
return index - constants::LongBuffs + EQEmu::constants::LongBuffs;
|
||||
// we're a normal buff
|
||||
return index; // as long as we guard against bad slots server side, we should be fine
|
||||
}
|
||||
} /*RoF*/
|
||||
|
||||
+102
-99
@@ -29,7 +29,7 @@
|
||||
#include "../eq_packet_structs.h"
|
||||
#include "../misc_functions.h"
|
||||
#include "../string_util.h"
|
||||
#include "../inventory_profile.h"
|
||||
#include "../item.h"
|
||||
#include "rof2_structs.h"
|
||||
#include "../rulesys.h"
|
||||
|
||||
@@ -45,7 +45,7 @@ namespace RoF2
|
||||
static OpcodeManager *opcodes = nullptr;
|
||||
static Strategy struct_strategy;
|
||||
|
||||
void SerializeItem(EQEmu::OutBuffer& ob, const EQEmu::ItemInstance *inst, int16 slot_id, uint8 depth, ItemPacketType packet_type);
|
||||
void SerializeItem(EQEmu::OutBuffer& ob, const ItemInst *inst, int16 slot_id, uint8 depth, ItemPacketType packet_type);
|
||||
|
||||
// server to client inventory location converters
|
||||
static inline structs::InventorySlot_Struct ServerToRoF2Slot(uint32 serverSlot, ItemPacketType PacketType = ItemPacketInvalid);
|
||||
@@ -66,9 +66,6 @@ namespace RoF2
|
||||
static inline CastingSlot ServerToRoF2CastingSlot(EQEmu::CastingSlot slot);
|
||||
static inline EQEmu::CastingSlot RoF2ToServerCastingSlot(CastingSlot slot);
|
||||
|
||||
static inline int ServerToRoF2BuffSlot(int index);
|
||||
static inline int RoF2ToServerBuffSlot(int index);
|
||||
|
||||
void Register(EQStreamIdentifier &into)
|
||||
{
|
||||
//create our opcode manager if we havent already
|
||||
@@ -495,7 +492,18 @@ namespace RoF2
|
||||
OUT(buff.y);
|
||||
OUT(buff.x);
|
||||
OUT(buff.z);
|
||||
eq->slotid = ServerToRoF2BuffSlot(emu->slotid);
|
||||
uint16 buffslot = emu->slotid;
|
||||
// Not sure if this is needs amending for RoF2 yet.
|
||||
if (buffslot >= 25)
|
||||
{
|
||||
buffslot += 17;
|
||||
}
|
||||
// TODO: We should really just deal with these "server side"
|
||||
// so we can have clients not limited to other clients.
|
||||
// This fixes discs, songs were changed to 20
|
||||
if (buffslot == 54)
|
||||
buffslot = 62;
|
||||
eq->slotid = buffslot;
|
||||
// TODO: implement slot_data stuff
|
||||
if (emu->bufffade == 1)
|
||||
eq->bufffade = 1;
|
||||
@@ -511,10 +519,10 @@ namespace RoF2
|
||||
outapp->WriteUInt32(0); // tic timer
|
||||
outapp->WriteUInt8(0); // Type of OP_BuffCreate packet ?
|
||||
outapp->WriteUInt16(1); // 1 buff in this packet
|
||||
outapp->WriteUInt32(eq->slotid);
|
||||
outapp->WriteUInt32(buffslot);
|
||||
outapp->WriteUInt32(0xffffffff); // SpellID (0xffff to remove)
|
||||
outapp->WriteUInt32(0); // Duration
|
||||
outapp->WriteUInt32(0); // numhits
|
||||
outapp->WriteUInt32(0); // ?
|
||||
outapp->WriteUInt8(0); // Caster name
|
||||
outapp->WriteUInt8(0); // Type
|
||||
}
|
||||
@@ -538,9 +546,21 @@ namespace RoF2
|
||||
__packet->WriteUInt8(emu->all_buffs); // 1 indicates all buffs on the player (0 to add or remove a single buff)
|
||||
__packet->WriteUInt16(emu->count);
|
||||
|
||||
for (int i = 0; i < emu->count; ++i)
|
||||
for (uint16 i = 0; i < emu->count; ++i)
|
||||
{
|
||||
__packet->WriteUInt32(emu->type == 0 ? ServerToRoF2BuffSlot(emu->entries[i].buff_slot) : emu->entries[i].buff_slot);
|
||||
uint16 buffslot = emu->entries[i].buff_slot;
|
||||
// Not sure if this is needs amending for RoF2 yet.
|
||||
if (emu->entries[i].buff_slot >= 25)
|
||||
{
|
||||
buffslot += 17;
|
||||
}
|
||||
// TODO: We should really just deal with these "server side"
|
||||
// so we can have clients not limited to other clients.
|
||||
// This fixes discs, songs were changed to 20
|
||||
if (buffslot == 54)
|
||||
buffslot = 62;
|
||||
|
||||
__packet->WriteUInt32(buffslot);
|
||||
__packet->WriteUInt32(emu->entries[i].spell_id);
|
||||
__packet->WriteUInt32(emu->entries[i].tics_remaining);
|
||||
__packet->WriteUInt32(emu->entries[i].num_hits); // Unknown
|
||||
@@ -652,7 +672,7 @@ namespace RoF2
|
||||
ob.write((const char*)&item_count, sizeof(uint32));
|
||||
|
||||
for (int index = 0; index < item_count; ++index, ++eq) {
|
||||
SerializeItem(ob, (const EQEmu::ItemInstance*)eq->inst, eq->slot_id, 0, ItemPacketCharInventory);
|
||||
SerializeItem(ob, (const ItemInst*)eq->inst, eq->slot_id, 0, ItemPacketCharInventory);
|
||||
if (ob.tellp() == last_pos)
|
||||
Log.Out(Logs::General, Logs::Netcode, "[STRUCTS] Serialization failed on item slot %d during OP_CharInventory. Item skipped.", eq->slot_id);
|
||||
|
||||
@@ -1043,8 +1063,8 @@ namespace RoF2
|
||||
VARSTRUCT_ENCODE_TYPE(uint32, OutBuffer, emu->drop_id); // Some unique id
|
||||
VARSTRUCT_ENCODE_TYPE(uint32, OutBuffer, 0); // Same for all objects in the zone
|
||||
VARSTRUCT_ENCODE_TYPE(float, OutBuffer, emu->heading);
|
||||
VARSTRUCT_ENCODE_TYPE(float, OutBuffer, emu->tilt_x); // X tilt
|
||||
VARSTRUCT_ENCODE_TYPE(float, OutBuffer, emu->tilt_y); // Y tilt
|
||||
VARSTRUCT_ENCODE_TYPE(float, OutBuffer, 0); // X tilt
|
||||
VARSTRUCT_ENCODE_TYPE(float, OutBuffer, 0); // Y tilt
|
||||
VARSTRUCT_ENCODE_TYPE(float, OutBuffer, emu->size != 0 && (float)emu->size < 5000.f ? (float)((float)emu->size / 100.0f) : 1.f ); // This appears to be the size field. Hackish logic because some PEQ DB items were corrupt.
|
||||
VARSTRUCT_ENCODE_TYPE(float, OutBuffer, emu->y);
|
||||
VARSTRUCT_ENCODE_TYPE(float, OutBuffer, emu->x);
|
||||
@@ -1560,6 +1580,17 @@ namespace RoF2
|
||||
FINISH_ENCODE();
|
||||
}
|
||||
|
||||
ENCODE(OP_InterruptCast)
|
||||
{
|
||||
ENCODE_LENGTH_EXACT(InterruptCast_Struct);
|
||||
SETUP_DIRECT_ENCODE(InterruptCast_Struct, structs::InterruptCast_Struct);
|
||||
|
||||
OUT(spawnid);
|
||||
OUT(messageid);
|
||||
|
||||
FINISH_ENCODE();
|
||||
}
|
||||
|
||||
ENCODE(OP_ItemLinkResponse) { ENCODE_FORWARD(OP_ItemPacket); }
|
||||
|
||||
ENCODE(OP_ItemPacket)
|
||||
@@ -1579,7 +1610,7 @@ namespace RoF2
|
||||
|
||||
ob.write((const char*)__emu_buffer, 4);
|
||||
|
||||
SerializeItem(ob, (const EQEmu::ItemInstance*)int_struct->inst, int_struct->slot_id, 0, old_item_pkt->PacketType);
|
||||
SerializeItem(ob, (const ItemInst*)int_struct->inst, int_struct->slot_id, 0, old_item_pkt->PacketType);
|
||||
if (ob.tellp() == last_pos) {
|
||||
Log.Out(Logs::General, Logs::Netcode, "[STRUCTS] Serialization failed on item slot %d.", int_struct->slot_id);
|
||||
delete in;
|
||||
@@ -2134,7 +2165,7 @@ namespace RoF2
|
||||
|
||||
outapp->WriteUInt32(22); // Equipment count
|
||||
|
||||
for (int r = EQEmu::textures::textureBegin; r < EQEmu::textures::materialCount; r++)
|
||||
for (int r = EQEmu::textures::TextureBegin; r < EQEmu::textures::TextureCount; r++)
|
||||
{
|
||||
outapp->WriteUInt32(emu->item_material.Slot[r].Material);
|
||||
outapp->WriteUInt32(0);
|
||||
@@ -2154,9 +2185,9 @@ namespace RoF2
|
||||
outapp->WriteUInt32(0);
|
||||
}
|
||||
|
||||
outapp->WriteUInt32(EQEmu::textures::materialCount); // Equipment2 count
|
||||
outapp->WriteUInt32(EQEmu::textures::TextureCount); // Equipment2 count
|
||||
|
||||
for (int r = EQEmu::textures::textureBegin; r < EQEmu::textures::materialCount; r++)
|
||||
for (int r = EQEmu::textures::TextureBegin; r < EQEmu::textures::TextureCount; r++)
|
||||
{
|
||||
outapp->WriteUInt32(0);
|
||||
outapp->WriteUInt32(0);
|
||||
@@ -2165,7 +2196,7 @@ namespace RoF2
|
||||
outapp->WriteUInt32(0);
|
||||
}
|
||||
|
||||
outapp->WriteUInt32(EQEmu::textures::materialCount); // Tint Count
|
||||
outapp->WriteUInt32(EQEmu::textures::TextureCount); // Tint Count
|
||||
|
||||
for (int r = 0; r < 7; r++)
|
||||
{
|
||||
@@ -2175,7 +2206,7 @@ namespace RoF2
|
||||
outapp->WriteUInt32(0);
|
||||
outapp->WriteUInt32(0);
|
||||
|
||||
outapp->WriteUInt32(EQEmu::textures::materialCount); // Tint2 Count
|
||||
outapp->WriteUInt32(EQEmu::textures::TextureCount); // Tint2 Count
|
||||
|
||||
for (int r = 0; r < 7; r++)
|
||||
{
|
||||
@@ -3124,12 +3155,12 @@ namespace RoF2
|
||||
eq_cse->Gender = emu_cse->Gender;
|
||||
eq_cse->Face = emu_cse->Face;
|
||||
|
||||
for (int equip_index = 0; equip_index < EQEmu::textures::materialCount; equip_index++) {
|
||||
for (int equip_index = 0; equip_index < EQEmu::textures::TextureCount; equip_index++) {
|
||||
eq_cse->Equip[equip_index].Material = emu_cse->Equip[equip_index].Material;
|
||||
eq_cse->Equip[equip_index].Unknown1 = emu_cse->Equip[equip_index].Unknown1;
|
||||
eq_cse->Equip[equip_index].EliteMaterial = emu_cse->Equip[equip_index].EliteModel;
|
||||
eq_cse->Equip[equip_index].HeroForgeModel = emu_cse->Equip[equip_index].HerosForgeModel;
|
||||
eq_cse->Equip[equip_index].Material2 = emu_cse->Equip[equip_index].Unknown2;
|
||||
eq_cse->Equip[equip_index].EliteMaterial = emu_cse->Equip[equip_index].EliteMaterial;
|
||||
eq_cse->Equip[equip_index].HeroForgeModel = emu_cse->Equip[equip_index].HeroForgeModel;
|
||||
eq_cse->Equip[equip_index].Material2 = emu_cse->Equip[equip_index].Material2;
|
||||
eq_cse->Equip[equip_index].Color = emu_cse->Equip[equip_index].Color;
|
||||
}
|
||||
|
||||
@@ -4291,7 +4322,7 @@ namespace RoF2
|
||||
|
||||
if ((emu->NPC == 0) || (emu->race <= 12) || (emu->race == 128) || (emu->race == 130) || (emu->race == 330) || (emu->race == 522))
|
||||
{
|
||||
for (k = EQEmu::textures::textureBegin; k < EQEmu::textures::materialCount; ++k)
|
||||
for (k = EQEmu::textures::TextureBegin; k < EQEmu::textures::TextureCount; ++k)
|
||||
{
|
||||
{
|
||||
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, emu->equipment_tint.Slot[k].Color);
|
||||
@@ -4300,15 +4331,15 @@ namespace RoF2
|
||||
|
||||
structs::Texture_Struct *Equipment = (structs::Texture_Struct *)Buffer;
|
||||
|
||||
for (k = EQEmu::textures::textureBegin; k < EQEmu::textures::materialCount; k++) {
|
||||
for (k = EQEmu::textures::TextureBegin; k < EQEmu::textures::TextureCount; k++) {
|
||||
Equipment[k].Material = emu->equipment.Slot[k].Material;
|
||||
Equipment[k].Unknown1 = emu->equipment.Slot[k].Unknown1;
|
||||
Equipment[k].EliteMaterial = emu->equipment.Slot[k].EliteModel;
|
||||
Equipment[k].HeroForgeModel = emu->equipment.Slot[k].HerosForgeModel;
|
||||
Equipment[k].Material2 = emu->equipment.Slot[k].Unknown2;
|
||||
Equipment[k].EliteMaterial = emu->equipment.Slot[k].EliteMaterial;
|
||||
Equipment[k].HeroForgeModel = emu->equipment.Slot[k].HeroForgeModel;
|
||||
Equipment[k].Material2 = emu->equipment.Slot[k].Material2;
|
||||
}
|
||||
|
||||
Buffer += (sizeof(structs::Texture_Struct) * EQEmu::textures::materialCount);
|
||||
Buffer += (sizeof(structs::Texture_Struct) * EQEmu::textures::TextureCount);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -4520,7 +4551,7 @@ namespace RoF2
|
||||
IN(buff.unknown003);
|
||||
IN(buff.spellid);
|
||||
IN(buff.duration);
|
||||
emu->slotid = RoF2ToServerBuffSlot(eq->slotid);
|
||||
IN(slotid);
|
||||
IN(bufffade);
|
||||
|
||||
FINISH_DIRECT_DECODE();
|
||||
@@ -4533,7 +4564,7 @@ namespace RoF2
|
||||
DECODE_LENGTH_EXACT(structs::BuffRemoveRequest_Struct);
|
||||
SETUP_DIRECT_DECODE(BuffRemoveRequest_Struct, structs::BuffRemoveRequest_Struct);
|
||||
|
||||
emu->SlotID = RoF2ToServerBuffSlot(eq->SlotID);
|
||||
emu->SlotID = (eq->SlotID < 42) ? eq->SlotID : (eq->SlotID - 17);
|
||||
|
||||
IN(EntityID);
|
||||
|
||||
@@ -5036,7 +5067,7 @@ namespace RoF2
|
||||
|
||||
IN(item_id);
|
||||
int r;
|
||||
for (r = EQEmu::inventory::socketBegin; r < EQEmu::inventory::SocketCount; r++) {
|
||||
for (r = 0; r < EQEmu::legacy::ITEM_COMMON_SIZE; r++) {
|
||||
IN(augments[r]);
|
||||
}
|
||||
IN(link_hash);
|
||||
@@ -5469,9 +5500,9 @@ namespace RoF2
|
||||
return NextItemInstSerialNumber;
|
||||
}
|
||||
|
||||
void SerializeItem(EQEmu::OutBuffer& ob, const EQEmu::ItemInstance *inst, int16 slot_id_in, uint8 depth, ItemPacketType packet_type)
|
||||
void SerializeItem(EQEmu::OutBuffer& ob, const ItemInst *inst, int16 slot_id_in, uint8 depth, ItemPacketType packet_type)
|
||||
{
|
||||
const EQEmu::ItemData *item = inst->GetUnscaledItem();
|
||||
const EQEmu::ItemBase *item = inst->GetUnscaledItem();
|
||||
|
||||
RoF2::structs::ItemSerializationHeader hdr;
|
||||
|
||||
@@ -5525,7 +5556,7 @@ namespace RoF2
|
||||
|
||||
if (inst->GetOrnamentationIDFile() && inst->GetOrnamentationIcon()) {
|
||||
ornaIcon = inst->GetOrnamentationIcon();
|
||||
heroModel = inst->GetOrnamentHeroModel(EQEmu::InventoryProfile::CalcMaterialFromSlot(slot_id_in));
|
||||
heroModel = inst->GetOrnamentHeroModel(Inventory::CalcMaterialFromSlot(slot_id_in));
|
||||
|
||||
char tmp[30]; memset(tmp, 0x0, 30); sprintf(tmp, "IT%d", inst->GetOrnamentationIDFile());
|
||||
|
||||
@@ -5892,18 +5923,18 @@ namespace RoF2
|
||||
|
||||
ob.write((const char*)&subitem_count, sizeof(uint32));
|
||||
|
||||
for (uint32 index = EQEmu::inventory::containerBegin; index < EQEmu::inventory::ContainerCount; ++index) {
|
||||
EQEmu::ItemInstance* sub = inst->GetItem(index);
|
||||
for (uint32 index = SUB_INDEX_BEGIN; index < EQEmu::legacy::ITEM_CONTAINER_SIZE; ++index) {
|
||||
ItemInst* sub = inst->GetItem(index);
|
||||
if (!sub)
|
||||
continue;
|
||||
|
||||
int SubSlotNumber = INVALID_INDEX;
|
||||
if (slot_id_in >= EQEmu::legacy::GENERAL_BEGIN && slot_id_in <= EQEmu::legacy::GENERAL_END)
|
||||
SubSlotNumber = (((slot_id_in + 3) * EQEmu::inventory::ContainerCount) + index + 1);
|
||||
SubSlotNumber = (((slot_id_in + 3) * EQEmu::legacy::ITEM_CONTAINER_SIZE) + index + 1);
|
||||
else if (slot_id_in >= EQEmu::legacy::BANK_BEGIN && slot_id_in <= EQEmu::legacy::BANK_END)
|
||||
SubSlotNumber = (((slot_id_in - EQEmu::legacy::BANK_BEGIN) * EQEmu::inventory::ContainerCount) + EQEmu::legacy::BANK_BAGS_BEGIN + index);
|
||||
SubSlotNumber = (((slot_id_in - EQEmu::legacy::BANK_BEGIN) * EQEmu::legacy::ITEM_CONTAINER_SIZE) + EQEmu::legacy::BANK_BAGS_BEGIN + index);
|
||||
else if (slot_id_in >= EQEmu::legacy::SHARED_BANK_BEGIN && slot_id_in <= EQEmu::legacy::SHARED_BANK_END)
|
||||
SubSlotNumber = (((slot_id_in - EQEmu::legacy::SHARED_BANK_BEGIN) * EQEmu::inventory::ContainerCount) + EQEmu::legacy::SHARED_BANK_BAGS_BEGIN + index);
|
||||
SubSlotNumber = (((slot_id_in - EQEmu::legacy::SHARED_BANK_BEGIN) * EQEmu::legacy::ITEM_CONTAINER_SIZE) + EQEmu::legacy::SHARED_BANK_BAGS_BEGIN + index);
|
||||
else
|
||||
SubSlotNumber = slot_id_in;
|
||||
|
||||
@@ -5929,7 +5960,7 @@ namespace RoF2
|
||||
|
||||
uint32 TempSlot = 0;
|
||||
|
||||
if (serverSlot < 56 || serverSlot == EQEmu::inventory::slotPowerSource) { // Main Inventory and Cursor
|
||||
if (serverSlot < 56 || serverSlot == EQEmu::legacy::SlotPowerSource) { // Main Inventory and Cursor
|
||||
if (PacketType == ItemPacketLoot)
|
||||
{
|
||||
RoF2Slot.Type = invtype::InvTypeCorpse;
|
||||
@@ -5941,13 +5972,13 @@ namespace RoF2
|
||||
RoF2Slot.Slot = serverSlot;
|
||||
}
|
||||
|
||||
if (serverSlot == EQEmu::inventory::slotPowerSource)
|
||||
if (serverSlot == EQEmu::legacy::SlotPowerSource)
|
||||
RoF2Slot.Slot = invslot::PossessionsPowerSource;
|
||||
|
||||
else if (serverSlot >= EQEmu::inventory::slotCursor && PacketType != ItemPacketLoot) // Cursor and Extended Corpse Inventory
|
||||
else if (serverSlot >= EQEmu::legacy::SlotCursor && PacketType != ItemPacketLoot) // Cursor and Extended Corpse Inventory
|
||||
RoF2Slot.Slot += 3;
|
||||
|
||||
else if (serverSlot >= EQEmu::inventory::slotAmmo) // (> 20)
|
||||
else if (serverSlot >= EQEmu::legacy::SlotAmmo) // (> 20)
|
||||
RoF2Slot.Slot += 1;
|
||||
}
|
||||
|
||||
@@ -5959,8 +5990,8 @@ namespace RoF2
|
||||
else if (serverSlot >= EQEmu::legacy::GENERAL_BAGS_BEGIN && serverSlot <= EQEmu::legacy::CURSOR_BAG_END) { // (> 250 && < 341)
|
||||
RoF2Slot.Type = invtype::InvTypePossessions;
|
||||
TempSlot = serverSlot - 1;
|
||||
RoF2Slot.Slot = int(TempSlot / EQEmu::inventory::ContainerCount) - 2;
|
||||
RoF2Slot.SubIndex = TempSlot - ((RoF2Slot.Slot + 2) * EQEmu::inventory::ContainerCount);
|
||||
RoF2Slot.Slot = int(TempSlot / EQEmu::legacy::ITEM_CONTAINER_SIZE) - 2;
|
||||
RoF2Slot.SubIndex = TempSlot - ((RoF2Slot.Slot + 2) * EQEmu::legacy::ITEM_CONTAINER_SIZE);
|
||||
|
||||
if (RoF2Slot.Slot >= invslot::PossessionsGeneral9) // (> 30)
|
||||
RoF2Slot.Slot = invslot::PossessionsCursor;
|
||||
@@ -5977,8 +6008,8 @@ namespace RoF2
|
||||
RoF2Slot.Slot = TempSlot;
|
||||
|
||||
if (TempSlot > 30) { // (> 30)
|
||||
RoF2Slot.Slot = int(TempSlot / EQEmu::inventory::ContainerCount) - 3;
|
||||
RoF2Slot.SubIndex = TempSlot - ((RoF2Slot.Slot + 3) * EQEmu::inventory::ContainerCount);
|
||||
RoF2Slot.Slot = int(TempSlot / EQEmu::legacy::ITEM_CONTAINER_SIZE) - 3;
|
||||
RoF2Slot.SubIndex = TempSlot - ((RoF2Slot.Slot + 3) * EQEmu::legacy::ITEM_CONTAINER_SIZE);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5988,8 +6019,8 @@ namespace RoF2
|
||||
RoF2Slot.Slot = TempSlot;
|
||||
|
||||
if (TempSlot > 30) { // (> 30)
|
||||
RoF2Slot.Slot = int(TempSlot / EQEmu::inventory::ContainerCount) - 3;
|
||||
RoF2Slot.SubIndex = TempSlot - ((RoF2Slot.Slot + 3) * EQEmu::inventory::ContainerCount);
|
||||
RoF2Slot.Slot = int(TempSlot / EQEmu::legacy::ITEM_CONTAINER_SIZE) - 3;
|
||||
RoF2Slot.SubIndex = TempSlot - ((RoF2Slot.Slot + 3) * EQEmu::legacy::ITEM_CONTAINER_SIZE);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5999,8 +6030,8 @@ namespace RoF2
|
||||
RoF2Slot.Slot = TempSlot;
|
||||
|
||||
if (TempSlot > 30) {
|
||||
RoF2Slot.Slot = int(TempSlot / EQEmu::inventory::ContainerCount) - 3;
|
||||
RoF2Slot.SubIndex = TempSlot - ((RoF2Slot.Slot + 3) * EQEmu::inventory::ContainerCount);
|
||||
RoF2Slot.Slot = int(TempSlot / EQEmu::legacy::ITEM_CONTAINER_SIZE) - 3;
|
||||
RoF2Slot.SubIndex = TempSlot - ((RoF2Slot.Slot + 3) * EQEmu::legacy::ITEM_CONTAINER_SIZE);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -6038,16 +6069,16 @@ namespace RoF2
|
||||
|
||||
uint32 TempSlot = 0;
|
||||
|
||||
if (serverSlot < 56 || serverSlot == EQEmu::inventory::slotPowerSource) { // (< 52)
|
||||
if (serverSlot < 56 || serverSlot == EQEmu::legacy::SlotPowerSource) { // (< 52)
|
||||
RoF2Slot.Slot = serverSlot;
|
||||
|
||||
if (serverSlot == EQEmu::inventory::slotPowerSource)
|
||||
if (serverSlot == EQEmu::legacy::SlotPowerSource)
|
||||
RoF2Slot.Slot = invslot::PossessionsPowerSource;
|
||||
|
||||
else if (serverSlot >= EQEmu::inventory::slotCursor) // Cursor and Extended Corpse Inventory
|
||||
else if (serverSlot >= EQEmu::legacy::SlotCursor) // Cursor and Extended Corpse Inventory
|
||||
RoF2Slot.Slot += 3;
|
||||
|
||||
else if (serverSlot >= EQEmu::inventory::slotAmmo) // Ammo and Personl Inventory
|
||||
else if (serverSlot >= EQEmu::legacy::SlotAmmo) // Ammo and Personl Inventory
|
||||
RoF2Slot.Slot += 1;
|
||||
|
||||
/*else if (ServerSlot >= MainCursor) { // Cursor
|
||||
@@ -6060,8 +6091,8 @@ namespace RoF2
|
||||
|
||||
else if (serverSlot >= EQEmu::legacy::GENERAL_BAGS_BEGIN && serverSlot <= EQEmu::legacy::CURSOR_BAG_END) {
|
||||
TempSlot = serverSlot - 1;
|
||||
RoF2Slot.Slot = int(TempSlot / EQEmu::inventory::ContainerCount) - 2;
|
||||
RoF2Slot.SubIndex = TempSlot - ((RoF2Slot.Slot + 2) * EQEmu::inventory::ContainerCount);
|
||||
RoF2Slot.Slot = int(TempSlot / EQEmu::legacy::ITEM_CONTAINER_SIZE) - 2;
|
||||
RoF2Slot.SubIndex = TempSlot - ((RoF2Slot.Slot + 2) * EQEmu::legacy::ITEM_CONTAINER_SIZE);
|
||||
}
|
||||
|
||||
Log.Out(Logs::General, Logs::Netcode, "[ERROR] Convert Server Slot %i to RoF2 Slots: Main %i, Sub %i, Aug %i, Unk1 %i", serverSlot, RoF2Slot.Slot, RoF2Slot.SubIndex, RoF2Slot.AugIndex, RoF2Slot.Unknown01);
|
||||
@@ -6081,7 +6112,7 @@ namespace RoF2
|
||||
|
||||
if (rof2Slot.Type == invtype::InvTypePossessions && rof2Slot.Slot < 57) { // Worn/Personal Inventory and Cursor (< 51)
|
||||
if (rof2Slot.Slot == invslot::PossessionsPowerSource)
|
||||
TempSlot = EQEmu::inventory::slotPowerSource;
|
||||
TempSlot = EQEmu::legacy::SlotPowerSource;
|
||||
|
||||
else if (rof2Slot.Slot >= invslot::PossessionsCursor) // Cursor and Extended Corpse Inventory
|
||||
TempSlot = rof2Slot.Slot - 3;
|
||||
@@ -6103,8 +6134,8 @@ namespace RoF2
|
||||
else // Worn Slots
|
||||
TempSlot = rof2Slot.Slot;
|
||||
|
||||
if (rof2Slot.SubIndex >= EQEmu::inventory::containerBegin) // Bag Slots
|
||||
TempSlot = ((TempSlot + 3) * EQEmu::inventory::ContainerCount) + rof2Slot.SubIndex + 1;
|
||||
if (rof2Slot.SubIndex >= SUB_INDEX_BEGIN) // Bag Slots
|
||||
TempSlot = ((TempSlot + 3) * EQEmu::legacy::ITEM_CONTAINER_SIZE) + rof2Slot.SubIndex + 1;
|
||||
|
||||
ServerSlot = TempSlot;
|
||||
}
|
||||
@@ -6112,8 +6143,8 @@ namespace RoF2
|
||||
else if (rof2Slot.Type == invtype::InvTypeBank) {
|
||||
TempSlot = EQEmu::legacy::BANK_BEGIN;
|
||||
|
||||
if (rof2Slot.SubIndex >= EQEmu::inventory::containerBegin)
|
||||
TempSlot += ((rof2Slot.Slot + 3) * EQEmu::inventory::ContainerCount) + rof2Slot.SubIndex + 1;
|
||||
if (rof2Slot.SubIndex >= SUB_INDEX_BEGIN)
|
||||
TempSlot += ((rof2Slot.Slot + 3) * EQEmu::legacy::ITEM_CONTAINER_SIZE) + rof2Slot.SubIndex + 1;
|
||||
|
||||
else
|
||||
TempSlot += rof2Slot.Slot;
|
||||
@@ -6124,8 +6155,8 @@ namespace RoF2
|
||||
else if (rof2Slot.Type == invtype::InvTypeSharedBank) {
|
||||
TempSlot = EQEmu::legacy::SHARED_BANK_BEGIN;
|
||||
|
||||
if (rof2Slot.SubIndex >= EQEmu::inventory::containerBegin)
|
||||
TempSlot += ((rof2Slot.Slot + 3) * EQEmu::inventory::ContainerCount) + rof2Slot.SubIndex + 1;
|
||||
if (rof2Slot.SubIndex >= SUB_INDEX_BEGIN)
|
||||
TempSlot += ((rof2Slot.Slot + 3) * EQEmu::legacy::ITEM_CONTAINER_SIZE) + rof2Slot.SubIndex + 1;
|
||||
|
||||
else
|
||||
TempSlot += rof2Slot.Slot;
|
||||
@@ -6136,8 +6167,8 @@ namespace RoF2
|
||||
else if (rof2Slot.Type == invtype::InvTypeTrade) {
|
||||
TempSlot = EQEmu::legacy::TRADE_BEGIN;
|
||||
|
||||
if (rof2Slot.SubIndex >= EQEmu::inventory::containerBegin)
|
||||
TempSlot += ((rof2Slot.Slot + 3) * EQEmu::inventory::ContainerCount) + rof2Slot.SubIndex + 1;
|
||||
if (rof2Slot.SubIndex >= SUB_INDEX_BEGIN)
|
||||
TempSlot += ((rof2Slot.Slot + 3) * EQEmu::legacy::ITEM_CONTAINER_SIZE) + rof2Slot.SubIndex + 1;
|
||||
// OLD CODE:
|
||||
//TempSlot += 100 + (RoF2Slot.MainSlot * EmuConstants::ITEM_CONTAINER_SIZE) + RoF2Slot.SubSlot;
|
||||
|
||||
@@ -6150,7 +6181,7 @@ namespace RoF2
|
||||
else if (rof2Slot.Type == invtype::InvTypeWorld) {
|
||||
TempSlot = EQEmu::legacy::WORLD_BEGIN;
|
||||
|
||||
if (rof2Slot.Slot >= EQEmu::inventory::containerBegin)
|
||||
if (rof2Slot.Slot >= SUB_INDEX_BEGIN)
|
||||
TempSlot += rof2Slot.Slot;
|
||||
|
||||
ServerSlot = TempSlot;
|
||||
@@ -6185,7 +6216,7 @@ namespace RoF2
|
||||
|
||||
if (rof2Slot.Slot < 57) { // Worn/Personal Inventory and Cursor (< 33)
|
||||
if (rof2Slot.Slot == invslot::PossessionsPowerSource)
|
||||
TempSlot = EQEmu::inventory::slotPowerSource;
|
||||
TempSlot = EQEmu::legacy::SlotPowerSource;
|
||||
|
||||
else if (rof2Slot.Slot >= invslot::PossessionsCursor) // Cursor and Extended Corpse Inventory
|
||||
TempSlot = rof2Slot.Slot - 3;
|
||||
@@ -6202,8 +6233,8 @@ namespace RoF2
|
||||
else
|
||||
TempSlot = rof2Slot.Slot;
|
||||
|
||||
if (rof2Slot.SubIndex >= EQEmu::inventory::containerBegin) // Bag Slots
|
||||
TempSlot = ((TempSlot + 3) * EQEmu::inventory::ContainerCount) + rof2Slot.SubIndex + 1;
|
||||
if (rof2Slot.SubIndex >= SUB_INDEX_BEGIN) // Bag Slots
|
||||
TempSlot = ((TempSlot + 3) * EQEmu::legacy::ITEM_CONTAINER_SIZE) + rof2Slot.SubIndex + 1;
|
||||
|
||||
ServerSlot = TempSlot;
|
||||
}
|
||||
@@ -6358,32 +6389,4 @@ namespace RoF2
|
||||
return EQEmu::CastingSlot::Discipline;
|
||||
}
|
||||
}
|
||||
|
||||
// these should be optimized out for RoF2 since they should all boil down to return index :P
|
||||
// but lets leave it here for future proofing
|
||||
static inline int ServerToRoF2BuffSlot(int index)
|
||||
{
|
||||
// we're a disc
|
||||
if (index >= EQEmu::constants::LongBuffs + EQEmu::constants::ShortBuffs)
|
||||
return index - EQEmu::constants::LongBuffs - EQEmu::constants::ShortBuffs +
|
||||
constants::LongBuffs + constants::ShortBuffs;
|
||||
// we're a song
|
||||
if (index >= EQEmu::constants::LongBuffs)
|
||||
return index - EQEmu::constants::LongBuffs + constants::LongBuffs;
|
||||
// we're a normal buff
|
||||
return index; // as long as we guard against bad slots server side, we should be fine
|
||||
}
|
||||
|
||||
static inline int RoF2ToServerBuffSlot(int index)
|
||||
{
|
||||
// we're a disc
|
||||
if (index >= constants::LongBuffs + constants::ShortBuffs)
|
||||
return index - constants::LongBuffs - constants::ShortBuffs + EQEmu::constants::LongBuffs +
|
||||
EQEmu::constants::ShortBuffs;
|
||||
// we're a song
|
||||
if (index >= constants::LongBuffs)
|
||||
return index - constants::LongBuffs + EQEmu::constants::LongBuffs;
|
||||
// we're a normal buff
|
||||
return index; // as long as we guard against bad slots server side, we should be fine
|
||||
}
|
||||
} /*RoF2*/
|
||||
|
||||
@@ -277,14 +277,6 @@ namespace RoF2
|
||||
|
||||
const size_t SayLinkBodySize = 56;
|
||||
|
||||
const int LongBuffs = 42;
|
||||
const int ShortBuffs = 20;
|
||||
const int DiscBuffs = 1;
|
||||
const int TotalBuffs = LongBuffs + ShortBuffs + DiscBuffs;
|
||||
const int NPCBuffs = 97;
|
||||
const int PetBuffs = NPCBuffs;
|
||||
const int MercBuffs = LongBuffs;
|
||||
|
||||
} /*constants*/
|
||||
|
||||
namespace behavior {
|
||||
|
||||
@@ -85,6 +85,7 @@ E(OP_HPUpdate)
|
||||
E(OP_Illusion)
|
||||
E(OP_InspectBuffs)
|
||||
E(OP_InspectRequest)
|
||||
E(OP_InterruptCast)
|
||||
E(OP_ItemLinkResponse)
|
||||
E(OP_ItemPacket)
|
||||
E(OP_ItemVerifyReply)
|
||||
|
||||
@@ -190,7 +190,7 @@ struct TintProfile
|
||||
Tint_Struct Primary;
|
||||
Tint_Struct Secondary;
|
||||
};
|
||||
Tint_Struct Slot[EQEmu::textures::materialCount];
|
||||
Tint_Struct Slot[EQEmu::textures::TextureCount];
|
||||
};
|
||||
};
|
||||
|
||||
@@ -1082,7 +1082,7 @@ union
|
||||
/*00184*/ Texture_Struct equipment[22]; // Total Slots
|
||||
};
|
||||
/*00624*/ uint32 equip2_count; // Seen 9
|
||||
/*00628*/ Texture_Struct equipment2[EQEmu::textures::materialCount]; // Appears to be Visible slots, but all 0s
|
||||
/*00628*/ Texture_Struct equipment2[EQEmu::textures::TextureCount]; // Appears to be Visible slots, but all 0s
|
||||
/*00808*/ uint32 tint_count; // Seen 9
|
||||
/*00812*/ TintProfile item_tint; // RR GG BB 00
|
||||
/*00848*/ uint32 tint_count2; // Seen 9
|
||||
@@ -2423,7 +2423,7 @@ struct AdventureLeaderboard_Struct
|
||||
/*struct Item_Shop_Struct {
|
||||
uint16 merchantid;
|
||||
uint8 itemtype;
|
||||
ItemData item;
|
||||
ItemBase item;
|
||||
uint8 iss_unknown001[6];
|
||||
};*/
|
||||
|
||||
|
||||
@@ -268,14 +268,6 @@ namespace RoF
|
||||
|
||||
const size_t SayLinkBodySize = 55;
|
||||
|
||||
const int LongBuffs = 42;
|
||||
const int ShortBuffs = 20;
|
||||
const int DiscBuffs = 1;
|
||||
const int TotalBuffs = LongBuffs + ShortBuffs + DiscBuffs;
|
||||
const int NPCBuffs = 97;
|
||||
const int PetBuffs = NPCBuffs;
|
||||
const int MercBuffs = LongBuffs;
|
||||
|
||||
} /*constants*/
|
||||
|
||||
namespace behavior {
|
||||
|
||||
@@ -70,6 +70,7 @@ E(OP_HPUpdate)
|
||||
E(OP_Illusion)
|
||||
E(OP_InspectBuffs)
|
||||
E(OP_InspectRequest)
|
||||
E(OP_InterruptCast)
|
||||
E(OP_ItemLinkResponse)
|
||||
E(OP_ItemPacket)
|
||||
E(OP_ItemVerifyReply)
|
||||
|
||||
@@ -190,7 +190,7 @@ struct TintProfile
|
||||
Tint_Struct Primary;
|
||||
Tint_Struct Secondary;
|
||||
};
|
||||
Tint_Struct Slot[EQEmu::textures::materialCount];
|
||||
Tint_Struct Slot[EQEmu::textures::TextureCount];
|
||||
};
|
||||
};
|
||||
|
||||
@@ -2021,7 +2021,7 @@ struct LootingItem_Struct {
|
||||
/*004*/ uint32 looter;
|
||||
/*008*/ uint16 slot_id;
|
||||
/*010*/ uint16 unknown10;
|
||||
/*012*/ int32 auto_loot;
|
||||
/*012*/ uint32 auto_loot;
|
||||
/*016*/ uint32 unknown16;
|
||||
/*020*/
|
||||
};
|
||||
@@ -2450,7 +2450,7 @@ struct AdventureLeaderboard_Struct
|
||||
/*struct Item_Shop_Struct {
|
||||
uint16 merchantid;
|
||||
uint8 itemtype;
|
||||
ItemData item;
|
||||
ItemBase item;
|
||||
uint8 iss_unknown001[6];
|
||||
};*/
|
||||
|
||||
|
||||
+26
-57
@@ -29,7 +29,7 @@
|
||||
#include "../eq_packet_structs.h"
|
||||
#include "../misc_functions.h"
|
||||
#include "../string_util.h"
|
||||
#include "../item_instance.h"
|
||||
#include "../item.h"
|
||||
#include "sod_structs.h"
|
||||
#include "../rulesys.h"
|
||||
|
||||
@@ -43,7 +43,7 @@ namespace SoD
|
||||
static OpcodeManager *opcodes = nullptr;
|
||||
static Strategy struct_strategy;
|
||||
|
||||
void SerializeItem(EQEmu::OutBuffer& ob, const EQEmu::ItemInstance *inst, int16 slot_id, uint8 depth);
|
||||
void SerializeItem(EQEmu::OutBuffer& ob, const ItemInst *inst, int16 slot_id, uint8 depth);
|
||||
|
||||
// server to client inventory location converters
|
||||
static inline uint32 ServerToSoDSlot(uint32 ServerSlot);
|
||||
@@ -62,9 +62,6 @@ namespace SoD
|
||||
static inline CastingSlot ServerToSoDCastingSlot(EQEmu::CastingSlot slot);
|
||||
static inline EQEmu::CastingSlot SoDToServerCastingSlot(CastingSlot slot);
|
||||
|
||||
static inline int ServerToSoDBuffSlot(int index);
|
||||
static inline int SoDToServerBuffSlot(int index);
|
||||
|
||||
void Register(EQStreamIdentifier &into)
|
||||
{
|
||||
//create our opcode manager if we havent already
|
||||
@@ -318,7 +315,7 @@ namespace SoD
|
||||
OUT(buff.duration);
|
||||
OUT(buff.counters);
|
||||
OUT(buff.player_id);
|
||||
eq->slotid = ServerToSoDBuffSlot(emu->slotid);
|
||||
OUT(slotid);
|
||||
OUT(bufffade);
|
||||
|
||||
FINISH_ENCODE();
|
||||
@@ -399,7 +396,7 @@ namespace SoD
|
||||
ob.write((const char*)&item_count, sizeof(uint32));
|
||||
|
||||
for (int index = 0; index < item_count; ++index, ++eq) {
|
||||
SerializeItem(ob, (const EQEmu::ItemInstance*)eq->inst, eq->slot_id, 0);
|
||||
SerializeItem(ob, (const ItemInst*)eq->inst, eq->slot_id, 0);
|
||||
if (ob.tellp() == last_pos)
|
||||
Log.Out(Logs::General, Logs::Netcode, "[STRUCTS] Serialization failed on item slot %d during OP_CharInventory. Item skipped.", eq->slot_id);
|
||||
|
||||
@@ -1063,7 +1060,7 @@ namespace SoD
|
||||
|
||||
ob.write((const char*)__emu_buffer, 4);
|
||||
|
||||
SerializeItem(ob, (const EQEmu::ItemInstance*)int_struct->inst, int_struct->slot_id, 0);
|
||||
SerializeItem(ob, (const ItemInst*)int_struct->inst, int_struct->slot_id, 0);
|
||||
if (ob.tellp() == last_pos) {
|
||||
Log.Out(Logs::General, Logs::Netcode, "[STRUCTS] Serialization failed on item slot %d.", int_struct->slot_id);
|
||||
delete in;
|
||||
@@ -1561,7 +1558,7 @@ namespace SoD
|
||||
OUT(hairstyle);
|
||||
OUT(beard);
|
||||
// OUT(unknown00178[10]);
|
||||
for (r = EQEmu::textures::textureBegin; r < EQEmu::textures::materialCount; r++) {
|
||||
for (r = EQEmu::textures::TextureBegin; r < EQEmu::textures::TextureCount; r++) {
|
||||
eq->equipment.Slot[r].Material = emu->item_material.Slot[r].Material;
|
||||
eq->equipment.Slot[r].Unknown1 = 0;
|
||||
eq->equipment.Slot[r].EliteMaterial = 0;
|
||||
@@ -2001,10 +1998,10 @@ namespace SoD
|
||||
eq_cse->HairColor = emu_cse->HairColor;
|
||||
eq_cse->Face = emu_cse->Face;
|
||||
|
||||
for (int equip_index = EQEmu::textures::textureBegin; equip_index < EQEmu::textures::materialCount; equip_index++) {
|
||||
for (int equip_index = 0; equip_index < EQEmu::textures::TextureCount; equip_index++) {
|
||||
eq_cse->Equip[equip_index].Material = emu_cse->Equip[equip_index].Material;
|
||||
eq_cse->Equip[equip_index].Unknown1 = emu_cse->Equip[equip_index].Unknown1;
|
||||
eq_cse->Equip[equip_index].EliteMaterial = emu_cse->Equip[equip_index].EliteModel;
|
||||
eq_cse->Equip[equip_index].EliteMaterial = emu_cse->Equip[equip_index].EliteMaterial;
|
||||
eq_cse->Equip[equip_index].Color = emu_cse->Equip[equip_index].Color;
|
||||
}
|
||||
|
||||
@@ -2571,7 +2568,7 @@ namespace SoD
|
||||
float SpawnSize = emu->size;
|
||||
if (!((emu->NPC == 0) || (emu->race <= 12) || (emu->race == 128) || (emu->race == 130) || (emu->race == 330) || (emu->race == 522)))
|
||||
{
|
||||
PacketSize -= (sizeof(structs::Texture_Struct) * EQEmu::textures::materialCount);
|
||||
PacketSize -= (sizeof(structs::Texture_Struct) * EQEmu::textures::TextureCount);
|
||||
|
||||
if (emu->size == 0)
|
||||
{
|
||||
@@ -2768,7 +2765,7 @@ namespace SoD
|
||||
|
||||
if ((emu->NPC == 0) || (emu->race <= 12) || (emu->race == 128) || (emu->race == 130) || (emu->race == 330) || (emu->race == 522))
|
||||
{
|
||||
for (k = EQEmu::textures::textureBegin; k < EQEmu::textures::materialCount; ++k)
|
||||
for (k = EQEmu::textures::TextureBegin; k < EQEmu::textures::TextureCount; ++k)
|
||||
{
|
||||
{
|
||||
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, emu->equipment_tint.Slot[k].Color);
|
||||
@@ -2795,13 +2792,13 @@ namespace SoD
|
||||
{
|
||||
structs::Texture_Struct *Equipment = (structs::Texture_Struct *)Buffer;
|
||||
|
||||
for (k = EQEmu::textures::textureBegin; k < EQEmu::textures::materialCount; k++) {
|
||||
for (k = EQEmu::textures::TextureBegin; k < EQEmu::textures::TextureCount; k++) {
|
||||
Equipment[k].Material = emu->equipment.Slot[k].Material;
|
||||
Equipment[k].Unknown1 = emu->equipment.Slot[k].Unknown1;
|
||||
Equipment[k].EliteMaterial = emu->equipment.Slot[k].EliteModel;
|
||||
Equipment[k].EliteMaterial = emu->equipment.Slot[k].EliteMaterial;
|
||||
}
|
||||
|
||||
Buffer += (sizeof(structs::Texture_Struct) * EQEmu::textures::materialCount);
|
||||
Buffer += (sizeof(structs::Texture_Struct) * EQEmu::textures::TextureCount);
|
||||
}
|
||||
if (strlen(emu->title))
|
||||
{
|
||||
@@ -2924,8 +2921,8 @@ namespace SoD
|
||||
IN(buff.bard_modifier);
|
||||
IN(buff.spellid);
|
||||
IN(buff.duration);
|
||||
IN(buff.counters);
|
||||
emu->slotid = SoDToServerBuffSlot(eq->slotid);
|
||||
IN(buff.counters)
|
||||
IN(slotid);
|
||||
IN(bufffade);
|
||||
|
||||
FINISH_DIRECT_DECODE();
|
||||
@@ -3249,10 +3246,8 @@ namespace SoD
|
||||
DECODE_LENGTH_EXACT(structs::LoadSpellSet_Struct);
|
||||
SETUP_DIRECT_DECODE(LoadSpellSet_Struct, structs::LoadSpellSet_Struct);
|
||||
|
||||
for (int i = 0; i < structs::MAX_PP_MEMSPELL; ++i)
|
||||
for (uint32 i = 0; i < MAX_PP_MEMSPELL; ++i)
|
||||
emu->spell[i] = eq->spell[i];
|
||||
for (int i = structs::MAX_PP_MEMSPELL; i < MAX_PP_MEMSPELL; ++i)
|
||||
emu->spell[i] = 0xFFFFFFFF;
|
||||
|
||||
FINISH_DIRECT_DECODE();
|
||||
}
|
||||
@@ -3556,9 +3551,9 @@ namespace SoD
|
||||
return NextItemInstSerialNumber;
|
||||
}
|
||||
|
||||
void SerializeItem(EQEmu::OutBuffer& ob, const EQEmu::ItemInstance *inst, int16 slot_id_in, uint8 depth)
|
||||
void SerializeItem(EQEmu::OutBuffer& ob, const ItemInst *inst, int16 slot_id_in, uint8 depth)
|
||||
{
|
||||
const EQEmu::ItemData *item = inst->GetUnscaledItem();
|
||||
const EQEmu::ItemBase *item = inst->GetUnscaledItem();
|
||||
|
||||
SoD::structs::ItemSerializationHeader hdr;
|
||||
|
||||
@@ -3872,18 +3867,18 @@ namespace SoD
|
||||
|
||||
ob.write((const char*)&subitem_count, sizeof(uint32));
|
||||
|
||||
for (uint32 index = EQEmu::inventory::containerBegin; index < EQEmu::inventory::ContainerCount; ++index) {
|
||||
EQEmu::ItemInstance* sub = inst->GetItem(index);
|
||||
for (uint32 index = SUB_INDEX_BEGIN; index < EQEmu::legacy::ITEM_CONTAINER_SIZE; ++index) {
|
||||
ItemInst* sub = inst->GetItem(index);
|
||||
if (!sub)
|
||||
continue;
|
||||
|
||||
int SubSlotNumber = INVALID_INDEX;
|
||||
if (slot_id_in >= EQEmu::legacy::GENERAL_BEGIN && slot_id_in <= EQEmu::legacy::GENERAL_END)
|
||||
SubSlotNumber = (((slot_id_in + 3) * EQEmu::inventory::ContainerCount) + index + 1);
|
||||
SubSlotNumber = (((slot_id_in + 3) * EQEmu::legacy::ITEM_CONTAINER_SIZE) + index + 1);
|
||||
else if (slot_id_in >= EQEmu::legacy::BANK_BEGIN && slot_id_in <= EQEmu::legacy::BANK_END)
|
||||
SubSlotNumber = (((slot_id_in - EQEmu::legacy::BANK_BEGIN) * EQEmu::inventory::ContainerCount) + EQEmu::legacy::BANK_BAGS_BEGIN + index);
|
||||
SubSlotNumber = (((slot_id_in - EQEmu::legacy::BANK_BEGIN) * EQEmu::legacy::ITEM_CONTAINER_SIZE) + EQEmu::legacy::BANK_BAGS_BEGIN + index);
|
||||
else if (slot_id_in >= EQEmu::legacy::SHARED_BANK_BEGIN && slot_id_in <= EQEmu::legacy::SHARED_BANK_END)
|
||||
SubSlotNumber = (((slot_id_in - EQEmu::legacy::SHARED_BANK_BEGIN) * EQEmu::inventory::ContainerCount) + EQEmu::legacy::SHARED_BANK_BAGS_BEGIN + index);
|
||||
SubSlotNumber = (((slot_id_in - EQEmu::legacy::SHARED_BANK_BEGIN) * EQEmu::legacy::ITEM_CONTAINER_SIZE) + EQEmu::legacy::SHARED_BANK_BAGS_BEGIN + index);
|
||||
else
|
||||
SubSlotNumber = slot_id_in;
|
||||
|
||||
@@ -3901,7 +3896,7 @@ namespace SoD
|
||||
{
|
||||
uint32 SoDSlot = 0;
|
||||
|
||||
if (serverSlot >= EQEmu::inventory::slotAmmo && serverSlot <= 53) // Cursor/Ammo/Power Source and Normal Inventory Slots
|
||||
if (serverSlot >= EQEmu::legacy::SlotAmmo && serverSlot <= 53) // Cursor/Ammo/Power Source and Normal Inventory Slots
|
||||
SoDSlot = serverSlot + 1;
|
||||
else if (serverSlot >= EQEmu::legacy::GENERAL_BAGS_BEGIN && serverSlot <= EQEmu::legacy::CURSOR_BAG_END)
|
||||
SoDSlot = serverSlot + 11;
|
||||
@@ -3909,7 +3904,7 @@ namespace SoD
|
||||
SoDSlot = serverSlot + 1;
|
||||
else if (serverSlot >= EQEmu::legacy::SHARED_BANK_BAGS_BEGIN && serverSlot <= EQEmu::legacy::SHARED_BANK_BAGS_END)
|
||||
SoDSlot = serverSlot + 1;
|
||||
else if (serverSlot == EQEmu::inventory::slotPowerSource)
|
||||
else if (serverSlot == EQEmu::legacy::SlotPowerSource)
|
||||
SoDSlot = invslot::PossessionsPowerSource;
|
||||
else
|
||||
SoDSlot = serverSlot;
|
||||
@@ -3935,7 +3930,7 @@ namespace SoD
|
||||
else if (sodSlot >= invbag::SharedBankBagsBegin && sodSlot <= invbag::SharedBankBagsEnd)
|
||||
ServerSlot = sodSlot - 1;
|
||||
else if (sodSlot == invslot::PossessionsPowerSource)
|
||||
ServerSlot = EQEmu::inventory::slotPowerSource;
|
||||
ServerSlot = EQEmu::legacy::SlotPowerSource;
|
||||
else
|
||||
ServerSlot = sodSlot;
|
||||
return ServerSlot;
|
||||
@@ -4091,30 +4086,4 @@ namespace SoD
|
||||
return EQEmu::CastingSlot::Discipline;
|
||||
}
|
||||
}
|
||||
|
||||
static inline int ServerToSoDBuffSlot(int index)
|
||||
{
|
||||
// we're a disc
|
||||
if (index >= EQEmu::constants::LongBuffs + EQEmu::constants::ShortBuffs)
|
||||
return index - EQEmu::constants::LongBuffs - EQEmu::constants::ShortBuffs +
|
||||
constants::LongBuffs + constants::ShortBuffs;
|
||||
// we're a song
|
||||
if (index >= EQEmu::constants::LongBuffs)
|
||||
return index - EQEmu::constants::LongBuffs + constants::LongBuffs;
|
||||
// we're a normal buff
|
||||
return index; // as long as we guard against bad slots server side, we should be fine
|
||||
}
|
||||
|
||||
static inline int SoDToServerBuffSlot(int index)
|
||||
{
|
||||
// we're a disc
|
||||
if (index >= constants::LongBuffs + constants::ShortBuffs)
|
||||
return index - constants::LongBuffs - constants::ShortBuffs + EQEmu::constants::LongBuffs +
|
||||
EQEmu::constants::ShortBuffs;
|
||||
// we're a song
|
||||
if (index >= constants::LongBuffs)
|
||||
return index - constants::LongBuffs + EQEmu::constants::LongBuffs;
|
||||
// we're a normal buff
|
||||
return index; // as long as we guard against bad slots server side, we should be fine
|
||||
}
|
||||
} /*SoD*/
|
||||
|
||||
@@ -295,14 +295,6 @@ namespace SoD
|
||||
|
||||
const size_t SayLinkBodySize = 50;
|
||||
|
||||
const int LongBuffs = 25;
|
||||
const int ShortBuffs = 15;
|
||||
const int DiscBuffs = 1;
|
||||
const int TotalBuffs = LongBuffs + ShortBuffs + DiscBuffs;
|
||||
const int NPCBuffs = 85;
|
||||
const int PetBuffs = NPCBuffs;
|
||||
const int MercBuffs = LongBuffs;
|
||||
|
||||
} /*constants*/
|
||||
|
||||
namespace behavior {
|
||||
|
||||
@@ -149,7 +149,7 @@ struct TintProfile
|
||||
Tint_Struct Primary;
|
||||
Tint_Struct Secondary;
|
||||
};
|
||||
Tint_Struct Slot[EQEmu::textures::materialCount];
|
||||
Tint_Struct Slot[EQEmu::textures::TextureCount];
|
||||
};
|
||||
};
|
||||
|
||||
@@ -178,7 +178,7 @@ struct TextureProfile
|
||||
Texture_Struct Primary;
|
||||
Texture_Struct Secondary;
|
||||
};
|
||||
Texture_Struct Slot[EQEmu::textures::materialCount];
|
||||
Texture_Struct Slot[EQEmu::textures::TextureCount];
|
||||
};
|
||||
|
||||
TextureProfile();
|
||||
@@ -195,7 +195,7 @@ struct CharacterSelectEntry_Struct
|
||||
/*0000*/ uint8 Beard; //
|
||||
/*0001*/ uint8 HairColor; //
|
||||
/*0000*/ uint8 Face; //
|
||||
/*0000*/ CharSelectEquip Equip[EQEmu::textures::materialCount];
|
||||
/*0000*/ CharSelectEquip Equip[EQEmu::textures::TextureCount];
|
||||
/*0000*/ uint32 PrimaryIDFile; //
|
||||
/*0000*/ uint32 SecondaryIDFile; //
|
||||
/*0000*/ uint8 Unknown15; // 0xff
|
||||
@@ -1666,7 +1666,7 @@ struct LootingItem_Struct {
|
||||
/*000*/ uint32 lootee;
|
||||
/*004*/ uint32 looter;
|
||||
/*008*/ uint32 slot_id;
|
||||
/*012*/ int32 auto_loot;
|
||||
/*012*/ uint32 auto_loot;
|
||||
/*016*/ uint32 unknown16;
|
||||
/*020*/
|
||||
};
|
||||
@@ -1880,7 +1880,8 @@ struct Merchant_Sell_Struct {
|
||||
/*004*/ uint32 playerid; // Player's entity id
|
||||
/*008*/ uint32 itemslot;
|
||||
/*012*/ uint32 unknown12;
|
||||
/*016*/ uint32 quantity;
|
||||
/*016*/ uint8 quantity; // Already sold
|
||||
/*017*/ uint8 Unknown017[3];
|
||||
/*020*/ uint32 Unknown020;
|
||||
/*024*/ uint32 price;
|
||||
/*028*/ uint32 pricehighorderbits; // It appears the price is 64 bits in SoD+
|
||||
@@ -1970,7 +1971,7 @@ struct AdventureLeaderboard_Struct
|
||||
/*struct Item_Shop_Struct {
|
||||
uint16 merchantid;
|
||||
uint8 itemtype;
|
||||
ItemData item;
|
||||
ItemBase item;
|
||||
uint8 iss_unknown001[6];
|
||||
};*/
|
||||
|
||||
|
||||
+22
-66
@@ -29,7 +29,7 @@
|
||||
#include "../eq_packet_structs.h"
|
||||
#include "../misc_functions.h"
|
||||
#include "../string_util.h"
|
||||
#include "../item_instance.h"
|
||||
#include "../item.h"
|
||||
#include "sof_structs.h"
|
||||
#include "../rulesys.h"
|
||||
|
||||
@@ -43,7 +43,7 @@ namespace SoF
|
||||
static OpcodeManager *opcodes = nullptr;
|
||||
static Strategy struct_strategy;
|
||||
|
||||
void SerializeItem(EQEmu::OutBuffer& ob, const EQEmu::ItemInstance *inst, int16 slot_id, uint8 depth);
|
||||
void SerializeItem(EQEmu::OutBuffer& ob, const ItemInst *inst, int16 slot_id, uint8 depth);
|
||||
|
||||
// server to client inventory location converters
|
||||
static inline uint32 ServerToSoFSlot(uint32 serverSlot);
|
||||
@@ -62,9 +62,6 @@ namespace SoF
|
||||
static inline CastingSlot ServerToSoFCastingSlot(EQEmu::CastingSlot slot);
|
||||
static inline EQEmu::CastingSlot SoFToServerCastingSlot(CastingSlot slot, uint32 itemlocation);
|
||||
|
||||
static inline int ServerToSoFBuffSlot(int index);
|
||||
static inline int SoFToServerBuffSlot(int index);
|
||||
|
||||
void Register(EQStreamIdentifier &into)
|
||||
{
|
||||
//create our opcode manager if we havent already
|
||||
@@ -300,7 +297,7 @@ namespace SoF
|
||||
OUT(buff.duration);
|
||||
OUT(buff.counters);
|
||||
OUT(buff.player_id);
|
||||
eq->slotid = ServerToSoFBuffSlot(emu->slotid);
|
||||
OUT(slotid);
|
||||
OUT(bufffade);
|
||||
|
||||
FINISH_ENCODE();
|
||||
@@ -381,7 +378,7 @@ namespace SoF
|
||||
ob.write((const char*)&item_count, sizeof(uint32));
|
||||
|
||||
for (int index = 0; index < item_count; ++index, ++eq) {
|
||||
SerializeItem(ob, (const EQEmu::ItemInstance*)eq->inst, eq->slot_id, 0);
|
||||
SerializeItem(ob, (const ItemInst*)eq->inst, eq->slot_id, 0);
|
||||
if (ob.tellp() == last_pos)
|
||||
Log.Out(Logs::General, Logs::Netcode, "[STRUCTS] Serialization failed on item slot %d during OP_CharInventory. Item skipped.", eq->slot_id);
|
||||
|
||||
@@ -860,7 +857,7 @@ namespace SoF
|
||||
|
||||
ob.write((const char*)__emu_buffer, 4);
|
||||
|
||||
SerializeItem(ob, (const EQEmu::ItemInstance*)int_struct->inst, int_struct->slot_id, 0);
|
||||
SerializeItem(ob, (const ItemInst*)int_struct->inst, int_struct->slot_id, 0);
|
||||
if (ob.tellp() == last_pos) {
|
||||
Log.Out(Logs::General, Logs::Netcode, "[STRUCTS] Serialization failed on item slot %d.", int_struct->slot_id);
|
||||
delete in;
|
||||
@@ -1233,7 +1230,7 @@ namespace SoF
|
||||
OUT(hairstyle);
|
||||
OUT(beard);
|
||||
// OUT(unknown00178[10]);
|
||||
for (r = EQEmu::textures::textureBegin; r < EQEmu::textures::materialCount; r++) {
|
||||
for (r = EQEmu::textures::TextureBegin; r < EQEmu::textures::TextureCount; r++) {
|
||||
eq->equipment.Slot[r].Material = emu->item_material.Slot[r].Material;
|
||||
eq->equipment.Slot[r].Unknown1 = 0;
|
||||
eq->equipment.Slot[r].EliteMaterial = 0;
|
||||
@@ -1673,10 +1670,10 @@ namespace SoF
|
||||
eq_cse->HairColor = emu_cse->HairColor;
|
||||
eq_cse->Face = emu_cse->Face;
|
||||
|
||||
for (int equip_index = EQEmu::textures::textureBegin; equip_index < EQEmu::textures::materialCount; equip_index++) {
|
||||
for (int equip_index = 0; equip_index < EQEmu::textures::TextureCount; equip_index++) {
|
||||
eq_cse->Equip[equip_index].Material = emu_cse->Equip[equip_index].Material;
|
||||
eq_cse->Equip[equip_index].Unknown1 = emu_cse->Equip[equip_index].Unknown1;
|
||||
eq_cse->Equip[equip_index].EliteMaterial = emu_cse->Equip[equip_index].EliteModel;
|
||||
eq_cse->Equip[equip_index].EliteMaterial = emu_cse->Equip[equip_index].EliteMaterial;
|
||||
eq_cse->Equip[equip_index].Color = emu_cse->Equip[equip_index].Color;
|
||||
}
|
||||
|
||||
@@ -2104,10 +2101,10 @@ namespace SoF
|
||||
eq->deity = emu->deity;
|
||||
eq->drakkin_heritage = emu->drakkin_heritage;
|
||||
eq->gender = emu->gender;
|
||||
for (k = EQEmu::textures::textureBegin; k < EQEmu::textures::materialCount; k++) {
|
||||
for (k = EQEmu::textures::TextureBegin; k < EQEmu::textures::TextureCount; k++) {
|
||||
eq->equipment.Slot[k].Material = emu->equipment.Slot[k].Material;
|
||||
eq->equipment.Slot[k].Unknown1 = emu->equipment.Slot[k].Unknown1;
|
||||
eq->equipment.Slot[k].EliteMaterial = emu->equipment.Slot[k].EliteModel;
|
||||
eq->equipment.Slot[k].EliteMaterial = emu->equipment.Slot[k].EliteMaterial;
|
||||
eq->equipment_tint.Slot[k].Color = emu->equipment_tint.Slot[k].Color;
|
||||
}
|
||||
eq->StandState = emu->StandState;
|
||||
@@ -2170,7 +2167,7 @@ namespace SoF
|
||||
strcpy(eq->name, emu->name);
|
||||
eq->petOwnerId = emu->petOwnerId;
|
||||
eq->pvp = 0; // 0 = non-pvp colored name, 1 = red pvp name
|
||||
for (k = EQEmu::textures::textureBegin; k < EQEmu::textures::materialCount; k++) {
|
||||
for (k = EQEmu::textures::TextureBegin; k < EQEmu::textures::TextureCount; k++) {
|
||||
eq->equipment_tint.Slot[k].Color = emu->equipment_tint.Slot[k].Color;
|
||||
}
|
||||
eq->anon = emu->anon;
|
||||
@@ -2378,7 +2375,7 @@ namespace SoF
|
||||
IN(buff.duration);
|
||||
IN(buff.counters);
|
||||
IN(buff.player_id);
|
||||
emu->slotid = SoFToServerBuffSlot(eq->slotid);
|
||||
IN(slotid);
|
||||
IN(bufffade);
|
||||
|
||||
FINISH_DIRECT_DECODE();
|
||||
@@ -2626,21 +2623,6 @@ namespace SoF
|
||||
FINISH_DIRECT_DECODE();
|
||||
}
|
||||
|
||||
DECODE(OP_LoadSpellSet)
|
||||
{
|
||||
DECODE_LENGTH_EXACT(structs::LoadSpellSet_Struct);
|
||||
SETUP_DIRECT_DECODE(LoadSpellSet_Struct, structs::LoadSpellSet_Struct);
|
||||
|
||||
for (int i = 0; i < structs::MAX_PP_MEMSPELL; ++i)
|
||||
IN(spell[i]);
|
||||
for (int i = structs::MAX_PP_MEMSPELL; i < MAX_PP_MEMSPELL; ++i)
|
||||
emu->spell[i] = 0xFFFFFFFF;
|
||||
|
||||
IN(unknown);
|
||||
|
||||
FINISH_DIRECT_DECODE();
|
||||
}
|
||||
|
||||
DECODE(OP_LootItem)
|
||||
{
|
||||
DECODE_LENGTH_EXACT(structs::LootingItem_Struct);
|
||||
@@ -2926,9 +2908,9 @@ namespace SoF
|
||||
return NextItemInstSerialNumber;
|
||||
}
|
||||
|
||||
void SerializeItem(EQEmu::OutBuffer& ob, const EQEmu::ItemInstance *inst, int16 slot_id_in, uint8 depth)
|
||||
void SerializeItem(EQEmu::OutBuffer& ob, const ItemInst *inst, int16 slot_id_in, uint8 depth)
|
||||
{
|
||||
const EQEmu::ItemData *item = inst->GetUnscaledItem();
|
||||
const EQEmu::ItemBase *item = inst->GetUnscaledItem();
|
||||
|
||||
SoF::structs::ItemSerializationHeader hdr;
|
||||
|
||||
@@ -3240,18 +3222,18 @@ namespace SoF
|
||||
|
||||
ob.write((const char*)&subitem_count, sizeof(uint32));
|
||||
|
||||
for (uint32 index = EQEmu::inventory::containerBegin; index < EQEmu::inventory::ContainerCount; ++index) {
|
||||
EQEmu::ItemInstance* sub = inst->GetItem(index);
|
||||
for (uint32 index = SUB_INDEX_BEGIN; index < EQEmu::legacy::ITEM_CONTAINER_SIZE; ++index) {
|
||||
ItemInst* sub = inst->GetItem(index);
|
||||
if (!sub)
|
||||
continue;
|
||||
|
||||
int SubSlotNumber = INVALID_INDEX;
|
||||
if (slot_id_in >= EQEmu::legacy::GENERAL_BEGIN && slot_id_in <= EQEmu::legacy::GENERAL_END)
|
||||
SubSlotNumber = (((slot_id_in + 3) * EQEmu::inventory::ContainerCount) + index + 1);
|
||||
SubSlotNumber = (((slot_id_in + 3) * EQEmu::legacy::ITEM_CONTAINER_SIZE) + index + 1);
|
||||
else if (slot_id_in >= EQEmu::legacy::BANK_BEGIN && slot_id_in <= EQEmu::legacy::BANK_END)
|
||||
SubSlotNumber = (((slot_id_in - EQEmu::legacy::BANK_BEGIN) * EQEmu::inventory::ContainerCount) + EQEmu::legacy::BANK_BAGS_BEGIN + index);
|
||||
SubSlotNumber = (((slot_id_in - EQEmu::legacy::BANK_BEGIN) * EQEmu::legacy::ITEM_CONTAINER_SIZE) + EQEmu::legacy::BANK_BAGS_BEGIN + index);
|
||||
else if (slot_id_in >= EQEmu::legacy::SHARED_BANK_BEGIN && slot_id_in <= EQEmu::legacy::SHARED_BANK_END)
|
||||
SubSlotNumber = (((slot_id_in - EQEmu::legacy::SHARED_BANK_BEGIN) * EQEmu::inventory::ContainerCount) + EQEmu::legacy::SHARED_BANK_BAGS_BEGIN + index);
|
||||
SubSlotNumber = (((slot_id_in - EQEmu::legacy::SHARED_BANK_BEGIN) * EQEmu::legacy::ITEM_CONTAINER_SIZE) + EQEmu::legacy::SHARED_BANK_BAGS_BEGIN + index);
|
||||
else
|
||||
SubSlotNumber = slot_id_in;
|
||||
|
||||
@@ -3269,7 +3251,7 @@ namespace SoF
|
||||
{
|
||||
uint32 SoFSlot = 0;
|
||||
|
||||
if (serverSlot >= EQEmu::inventory::slotAmmo && serverSlot <= 53) // Cursor/Ammo/Power Source and Normal Inventory Slots
|
||||
if (serverSlot >= EQEmu::legacy::SlotAmmo && serverSlot <= 53) // Cursor/Ammo/Power Source and Normal Inventory Slots
|
||||
SoFSlot = serverSlot + 1;
|
||||
else if (serverSlot >= EQEmu::legacy::GENERAL_BAGS_BEGIN && serverSlot <= EQEmu::legacy::CURSOR_BAG_END)
|
||||
SoFSlot = serverSlot + 11;
|
||||
@@ -3277,7 +3259,7 @@ namespace SoF
|
||||
SoFSlot = serverSlot + 1;
|
||||
else if (serverSlot >= EQEmu::legacy::SHARED_BANK_BAGS_BEGIN && serverSlot <= EQEmu::legacy::SHARED_BANK_BAGS_END)
|
||||
SoFSlot = serverSlot + 1;
|
||||
else if (serverSlot == EQEmu::inventory::slotPowerSource)
|
||||
else if (serverSlot == EQEmu::legacy::SlotPowerSource)
|
||||
SoFSlot = invslot::PossessionsPowerSource;
|
||||
else
|
||||
SoFSlot = serverSlot;
|
||||
@@ -3304,7 +3286,7 @@ namespace SoF
|
||||
else if (sofSlot >= invbag::SharedBankBagsBegin && sofSlot <= invbag::SharedBankBagsEnd)
|
||||
ServerSlot = sofSlot - 1;
|
||||
else if (sofSlot == invslot::PossessionsPowerSource)
|
||||
ServerSlot = EQEmu::inventory::slotPowerSource;
|
||||
ServerSlot = EQEmu::legacy::SlotPowerSource;
|
||||
else
|
||||
ServerSlot = sofSlot;
|
||||
|
||||
@@ -3464,30 +3446,4 @@ namespace SoF
|
||||
return EQEmu::CastingSlot::Discipline;
|
||||
}
|
||||
}
|
||||
|
||||
static inline int ServerToSoFBuffSlot(int index)
|
||||
{
|
||||
// we're a disc
|
||||
if (index >= EQEmu::constants::LongBuffs + EQEmu::constants::ShortBuffs)
|
||||
return index - EQEmu::constants::LongBuffs - EQEmu::constants::ShortBuffs +
|
||||
constants::LongBuffs + constants::ShortBuffs;
|
||||
// we're a song
|
||||
if (index >= EQEmu::constants::LongBuffs)
|
||||
return index - EQEmu::constants::LongBuffs + constants::LongBuffs;
|
||||
// we're a normal buff
|
||||
return index; // as long as we guard against bad slots server side, we should be fine
|
||||
}
|
||||
|
||||
static inline int SoFToServerBuffSlot(int index)
|
||||
{
|
||||
// we're a disc
|
||||
if (index >= constants::LongBuffs + constants::ShortBuffs)
|
||||
return index - constants::LongBuffs - constants::ShortBuffs + EQEmu::constants::LongBuffs +
|
||||
EQEmu::constants::ShortBuffs;
|
||||
// we're a song
|
||||
if (index >= constants::LongBuffs)
|
||||
return index - constants::LongBuffs + EQEmu::constants::LongBuffs;
|
||||
// we're a normal buff
|
||||
return index; // as long as we guard against bad slots server side, we should be fine
|
||||
}
|
||||
} /*SoF*/
|
||||
|
||||
@@ -295,14 +295,6 @@ namespace SoF
|
||||
|
||||
const size_t SayLinkBodySize = 50;
|
||||
|
||||
const int LongBuffs = 25;
|
||||
const int ShortBuffs = 15;
|
||||
const int DiscBuffs = 1;
|
||||
const int TotalBuffs = LongBuffs + ShortBuffs + DiscBuffs;
|
||||
const int NPCBuffs = 60;
|
||||
const int PetBuffs = 30;
|
||||
const int MercBuffs = 0;
|
||||
|
||||
} /*constants*/
|
||||
|
||||
namespace behavior {
|
||||
|
||||
@@ -111,7 +111,6 @@ D(OP_GroupFollow2)
|
||||
D(OP_InspectRequest)
|
||||
D(OP_ItemLinkClick)
|
||||
D(OP_ItemVerifyRequest)
|
||||
D(OP_LoadSpellSet)
|
||||
D(OP_LootItem)
|
||||
D(OP_MoveItem)
|
||||
D(OP_PetCommands)
|
||||
|
||||
@@ -149,7 +149,7 @@ struct TintProfile
|
||||
Tint_Struct Primary;
|
||||
Tint_Struct Secondary;
|
||||
};
|
||||
Tint_Struct Slot[EQEmu::textures::materialCount];
|
||||
Tint_Struct Slot[EQEmu::textures::TextureCount];
|
||||
};
|
||||
};
|
||||
|
||||
@@ -178,7 +178,7 @@ struct TextureProfile
|
||||
Texture_Struct Primary;
|
||||
Texture_Struct Secondary;
|
||||
};
|
||||
Texture_Struct Slot[EQEmu::textures::materialCount];
|
||||
Texture_Struct Slot[EQEmu::textures::TextureCount];
|
||||
};
|
||||
|
||||
TextureProfile();
|
||||
@@ -195,7 +195,7 @@ struct CharacterSelectEntry_Struct
|
||||
/*0000*/ uint8 Beard; //
|
||||
/*0001*/ uint8 HairColor; //
|
||||
/*0000*/ uint8 Face; //
|
||||
/*0000*/ CharSelectEquip Equip[EQEmu::textures::materialCount];
|
||||
/*0000*/ CharSelectEquip Equip[EQEmu::textures::TextureCount];
|
||||
/*0000*/ uint32 PrimaryIDFile; //
|
||||
/*0000*/ uint32 SecondaryIDFile; //
|
||||
/*0000*/ uint8 Unknown15; // 0xff
|
||||
@@ -1648,7 +1648,7 @@ struct LootingItem_Struct {
|
||||
/*002*/ uint32 looter;
|
||||
/*004*/ uint16 slot_id;
|
||||
/*006*/ uint8 unknown3[2];
|
||||
/*008*/ int32 auto_loot;
|
||||
/*008*/ uint32 auto_loot;
|
||||
};
|
||||
|
||||
struct GuildManageStatus_Struct{
|
||||
@@ -1859,7 +1859,8 @@ struct Merchant_Sell_Struct {
|
||||
/*004*/ uint32 playerid; // Player's entity id
|
||||
/*008*/ uint32 itemslot;
|
||||
uint32 unknown12;
|
||||
/*016*/ uint32 quantity;
|
||||
/*016*/ uint8 quantity; // Already sold
|
||||
/*017*/ uint8 Unknown016[3];
|
||||
/*020*/ uint32 price;
|
||||
};
|
||||
struct Merchant_Purchase_Struct {
|
||||
@@ -3728,11 +3729,6 @@ struct AnnoyingZoneUnknown_Struct {
|
||||
uint32 value; //always 4
|
||||
};
|
||||
|
||||
struct LoadSpellSet_Struct {
|
||||
uint32 spell[MAX_PP_MEMSPELL];
|
||||
uint32 unknown;
|
||||
};
|
||||
|
||||
struct BlockedBuffs_Struct {
|
||||
/*000*/ uint8 unknown000[80];
|
||||
/*080*/ uint8 unknown081;
|
||||
|
||||
+16
-100
@@ -30,7 +30,7 @@
|
||||
#include "../eq_packet_structs.h"
|
||||
#include "../misc_functions.h"
|
||||
#include "../string_util.h"
|
||||
#include "../item_instance.h"
|
||||
#include "../item.h"
|
||||
#include "titanium_structs.h"
|
||||
|
||||
#include <sstream>
|
||||
@@ -42,7 +42,7 @@ namespace Titanium
|
||||
static OpcodeManager *opcodes = nullptr;
|
||||
static Strategy struct_strategy;
|
||||
|
||||
void SerializeItem(EQEmu::OutBuffer& ob, const EQEmu::ItemInstance *inst, int16 slot_id_in, uint8 depth);
|
||||
void SerializeItem(EQEmu::OutBuffer& ob, const ItemInst *inst, int16 slot_id_in, uint8 depth);
|
||||
|
||||
// server to client inventory location converters
|
||||
static inline int16 ServerToTitaniumSlot(uint32 serverSlot);
|
||||
@@ -61,9 +61,6 @@ namespace Titanium
|
||||
static inline CastingSlot ServerToTitaniumCastingSlot(EQEmu::CastingSlot slot);
|
||||
static inline EQEmu::CastingSlot TitaniumToServerCastingSlot(CastingSlot slot, uint32 itemlocation);
|
||||
|
||||
static inline int ServerToTitaniumBuffSlot(int index);
|
||||
static inline int TitaniumToServerBuffSlot(int index);
|
||||
|
||||
void Register(EQStreamIdentifier &into)
|
||||
{
|
||||
auto Config = EQEmuConfig::get();
|
||||
@@ -273,7 +270,7 @@ namespace Titanium
|
||||
OUT(buff.duration);
|
||||
OUT(buff.counters);
|
||||
OUT(buff.player_id);
|
||||
eq->slotid = ServerToTitaniumBuffSlot(emu->slotid);
|
||||
OUT(slotid);
|
||||
OUT(bufffade);
|
||||
|
||||
FINISH_ENCODE();
|
||||
@@ -332,7 +329,7 @@ namespace Titanium
|
||||
EQEmu::OutBuffer::pos_type last_pos = ob.tellp();
|
||||
|
||||
for (int r = 0; r < itemcount; r++, eq++) {
|
||||
SerializeItem(ob, (const EQEmu::ItemInstance*)eq->inst, eq->slot_id, 0);
|
||||
SerializeItem(ob, (const ItemInst*)eq->inst, eq->slot_id, 0);
|
||||
if (ob.tellp() == last_pos)
|
||||
Log.Out(Logs::General, Logs::Netcode, "[STRUCTS] Serialization failed on item slot %d during OP_CharInventory. Item skipped.", eq->slot_id);
|
||||
|
||||
@@ -598,46 +595,6 @@ namespace Titanium
|
||||
dest->FastQueuePacket(&in, ack_req);
|
||||
}
|
||||
|
||||
ENCODE(OP_GroundSpawn)
|
||||
{
|
||||
// We are not encoding the spawn_id field here, but it doesn't appear to matter.
|
||||
//
|
||||
EQApplicationPacket *in = *p;
|
||||
*p = nullptr;
|
||||
|
||||
//store away the emu struct
|
||||
unsigned char *__emu_buffer = in->pBuffer;
|
||||
Object_Struct *emu = (Object_Struct *)__emu_buffer;
|
||||
|
||||
in->size = strlen(emu->object_name) + sizeof(structs::Object_Struct) - 1;
|
||||
in->pBuffer = new unsigned char[in->size];
|
||||
|
||||
structs::Object_Struct *eq = (structs::Object_Struct *) in->pBuffer;
|
||||
|
||||
eq->drop_id = emu->drop_id;
|
||||
eq->heading = emu->heading;
|
||||
eq->linked_list_addr[0] = 0;
|
||||
eq->linked_list_addr[1] = 0;
|
||||
strcpy(eq->object_name, emu->object_name);
|
||||
eq->object_type = emu->object_type;
|
||||
eq->spawn_id = 0;
|
||||
eq->unknown008[0] = 0;
|
||||
eq->unknown008[1] = 0;
|
||||
eq->unknown020 = 0;
|
||||
eq->unknown024 = 0;
|
||||
eq->unknown076 = 0;
|
||||
eq->unknown084 = 0xffffffff;
|
||||
eq->z = emu->z;
|
||||
eq->x = emu->x;
|
||||
eq->y = emu->y;
|
||||
eq->zone_id = emu->zone_id;
|
||||
eq->zone_instance = emu->zone_instance;
|
||||
|
||||
|
||||
delete[] __emu_buffer;
|
||||
dest->FastQueuePacket(&in, ack_req);
|
||||
}
|
||||
|
||||
ENCODE(OP_GuildMemberList)
|
||||
{
|
||||
//consume the packet
|
||||
@@ -818,7 +775,7 @@ namespace Titanium
|
||||
|
||||
ob.write((const char*)__emu_buffer, 4);
|
||||
|
||||
SerializeItem(ob, (const EQEmu::ItemInstance*)int_struct->inst, int_struct->slot_id, 0);
|
||||
SerializeItem(ob, (const ItemInst*)int_struct->inst, int_struct->slot_id, 0);
|
||||
if (ob.tellp() == last_pos) {
|
||||
Log.Out(Logs::General, Logs::Netcode, "[STRUCTS] Serialization failed on item slot %d.", int_struct->slot_id);
|
||||
delete in;
|
||||
@@ -984,7 +941,7 @@ namespace Titanium
|
||||
OUT(hairstyle);
|
||||
OUT(beard);
|
||||
// OUT(unknown00178[10]);
|
||||
for (r = EQEmu::textures::textureBegin; r < EQEmu::textures::materialCount; r++) {
|
||||
for (r = EQEmu::textures::TextureBegin; r < EQEmu::textures::TextureCount; r++) {
|
||||
OUT(item_material.Slot[r].Material);
|
||||
OUT(item_tint.Slot[r].Color);
|
||||
}
|
||||
@@ -1304,14 +1261,14 @@ namespace Titanium
|
||||
if (eq->Race[char_index] > 473)
|
||||
eq->Race[char_index] = 1;
|
||||
|
||||
for (int index = 0; index < EQEmu::textures::materialCount; ++index) {
|
||||
for (int index = 0; index < EQEmu::textures::TextureCount; ++index) {
|
||||
eq->CS_Colors[char_index].Slot[index].Color = emu_cse->Equip[index].Color;
|
||||
}
|
||||
|
||||
eq->BeardColor[char_index] = emu_cse->BeardColor;
|
||||
eq->HairStyle[char_index] = emu_cse->HairStyle;
|
||||
|
||||
for (int index = 0; index < EQEmu::textures::materialCount; ++index) {
|
||||
for (int index = 0; index < EQEmu::textures::TextureCount; ++index) {
|
||||
eq->Equip[char_index].Slot[index].Material = emu_cse->Equip[index].Material;
|
||||
}
|
||||
|
||||
@@ -1341,14 +1298,14 @@ namespace Titanium
|
||||
for (; char_index < 10; ++char_index) {
|
||||
eq->Race[char_index] = 0;
|
||||
|
||||
for (int index = 0; index < EQEmu::textures::materialCount; ++index) {
|
||||
for (int index = 0; index < EQEmu::textures::TextureCount; ++index) {
|
||||
eq->CS_Colors[char_index].Slot[index].Color = 0;
|
||||
}
|
||||
|
||||
eq->BeardColor[char_index] = 0;
|
||||
eq->HairStyle[char_index] = 0;
|
||||
|
||||
for (int index = 0; index < EQEmu::textures::materialCount; ++index) {
|
||||
for (int index = 0; index < EQEmu::textures::TextureCount; ++index) {
|
||||
eq->Equip[char_index].Slot[index].Material = 0;
|
||||
}
|
||||
|
||||
@@ -1680,7 +1637,7 @@ namespace Titanium
|
||||
eq->petOwnerId = emu->petOwnerId;
|
||||
eq->guildrank = emu->guildrank;
|
||||
// eq->unknown0194[3] = emu->unknown0194[3];
|
||||
for (k = EQEmu::textures::textureBegin; k < EQEmu::textures::materialCount; k++) {
|
||||
for (k = EQEmu::textures::TextureBegin; k < EQEmu::textures::TextureCount; k++) {
|
||||
eq->equipment.Slot[k].Material = emu->equipment.Slot[k].Material;
|
||||
eq->equipment_tint.Slot[k].Color = emu->equipment_tint.Slot[k].Color;
|
||||
}
|
||||
@@ -1782,7 +1739,7 @@ namespace Titanium
|
||||
IN(buff.duration);
|
||||
IN(buff.counters);
|
||||
IN(buff.player_id);
|
||||
emu->slotid = TitaniumToServerBuffSlot(eq->slotid);
|
||||
IN(slotid);
|
||||
IN(bufffade);
|
||||
|
||||
FINISH_DIRECT_DECODE();
|
||||
@@ -1981,21 +1938,6 @@ namespace Titanium
|
||||
FINISH_DIRECT_DECODE();
|
||||
}
|
||||
|
||||
DECODE(OP_LoadSpellSet)
|
||||
{
|
||||
DECODE_LENGTH_EXACT(structs::LoadSpellSet_Struct);
|
||||
SETUP_DIRECT_DECODE(LoadSpellSet_Struct, structs::LoadSpellSet_Struct);
|
||||
|
||||
for (int i = 0; i < structs::MAX_PP_MEMSPELL; ++i)
|
||||
IN(spell[i]);
|
||||
for (int i = structs::MAX_PP_MEMSPELL; i < MAX_PP_MEMSPELL; ++i)
|
||||
emu->spell[i] = 0xFFFFFFFF;
|
||||
|
||||
IN(unknown);
|
||||
|
||||
FINISH_DIRECT_DECODE();
|
||||
}
|
||||
|
||||
DECODE(OP_LootItem)
|
||||
{
|
||||
DECODE_LENGTH_EXACT(structs::LootingItem_Struct);
|
||||
@@ -2219,10 +2161,10 @@ namespace Titanium
|
||||
}
|
||||
|
||||
// file scope helper methods
|
||||
void SerializeItem(EQEmu::OutBuffer& ob, const EQEmu::ItemInstance *inst, int16 slot_id_in, uint8 depth)
|
||||
void SerializeItem(EQEmu::OutBuffer& ob, const ItemInst *inst, int16 slot_id_in, uint8 depth)
|
||||
{
|
||||
const char* protection = "\\\\\\\\\\";
|
||||
const EQEmu::ItemData* item = inst->GetUnscaledItem();
|
||||
const EQEmu::ItemBase* item = inst->GetUnscaledItem();
|
||||
|
||||
ob << StringFormat("%.*s%s", (depth ? (depth - 1) : 0), protection, (depth ? "\"" : "")); // For leading quotes (and protection) if a subitem;
|
||||
|
||||
@@ -2440,10 +2382,10 @@ namespace Titanium
|
||||
ob << StringFormat("%.*s\"", depth, protection); // Quotes (and protection, if needed) around static data
|
||||
|
||||
// Sub data
|
||||
for (int index = EQEmu::inventory::containerBegin; index < invbag::ItemBagSize; ++index) {
|
||||
for (int index = SUB_INDEX_BEGIN; index < invbag::ItemBagSize; ++index) {
|
||||
ob << '|';
|
||||
|
||||
EQEmu::ItemInstance* sub = inst->GetItem(index);
|
||||
ItemInst* sub = inst->GetItem(index);
|
||||
if (!sub)
|
||||
continue;
|
||||
|
||||
@@ -2635,30 +2577,4 @@ namespace Titanium
|
||||
return EQEmu::CastingSlot::Discipline;
|
||||
}
|
||||
}
|
||||
|
||||
static inline int ServerToTitaniumBuffSlot(int index)
|
||||
{
|
||||
// we're a disc
|
||||
if (index >= EQEmu::constants::LongBuffs + EQEmu::constants::ShortBuffs)
|
||||
return index - EQEmu::constants::LongBuffs - EQEmu::constants::ShortBuffs +
|
||||
constants::LongBuffs + constants::ShortBuffs;
|
||||
// we're a song
|
||||
if (index >= EQEmu::constants::LongBuffs)
|
||||
return index - EQEmu::constants::LongBuffs + constants::LongBuffs;
|
||||
// we're a normal buff
|
||||
return index; // as long as we guard against bad slots server side, we should be fine
|
||||
}
|
||||
|
||||
static inline int TitaniumToServerBuffSlot(int index)
|
||||
{
|
||||
// we're a disc
|
||||
if (index >= constants::LongBuffs + constants::ShortBuffs)
|
||||
return index - constants::LongBuffs - constants::ShortBuffs + EQEmu::constants::LongBuffs +
|
||||
EQEmu::constants::ShortBuffs;
|
||||
// we're a song
|
||||
if (index >= constants::LongBuffs)
|
||||
return index - constants::LongBuffs + EQEmu::constants::LongBuffs;
|
||||
// we're a normal buff
|
||||
return index; // as long as we guard against bad slots server side, we should be fine
|
||||
}
|
||||
} /*Titanium*/
|
||||
|
||||
@@ -294,14 +294,6 @@ namespace Titanium
|
||||
|
||||
const size_t SayLinkBodySize = 45;
|
||||
|
||||
const int LongBuffs = 25;
|
||||
const int ShortBuffs = 12;
|
||||
const int DiscBuffs = 1;
|
||||
const int TotalBuffs = LongBuffs + ShortBuffs + DiscBuffs;
|
||||
const int NPCBuffs = 60;
|
||||
const int PetBuffs = 30;
|
||||
const int MercBuffs = 0;
|
||||
|
||||
} /*constants*/
|
||||
|
||||
namespace behavior {
|
||||
|
||||
@@ -40,7 +40,6 @@ E(OP_DzLeaderStatus)
|
||||
E(OP_DzMemberList)
|
||||
E(OP_Emote)
|
||||
E(OP_FormattedMessage)
|
||||
E(OP_GroundSpawn)
|
||||
E(OP_GuildMemberLevelUpdate)
|
||||
E(OP_GuildMemberList)
|
||||
E(OP_Illusion)
|
||||
@@ -89,7 +88,6 @@ D(OP_InspectAnswer)
|
||||
D(OP_InspectRequest)
|
||||
D(OP_ItemLinkClick)
|
||||
D(OP_LFGuild)
|
||||
D(OP_LoadSpellSet)
|
||||
D(OP_LootItem)
|
||||
D(OP_MoveItem)
|
||||
D(OP_PetCommands)
|
||||
|
||||
@@ -144,7 +144,7 @@ struct TintProfile {
|
||||
Tint_Struct Primary;
|
||||
Tint_Struct Secondary;
|
||||
};
|
||||
Tint_Struct Slot[EQEmu::textures::materialCount];
|
||||
Tint_Struct Slot[EQEmu::textures::TextureCount];
|
||||
};
|
||||
};
|
||||
|
||||
@@ -167,7 +167,7 @@ struct TextureProfile
|
||||
Texture_Struct Primary;
|
||||
Texture_Struct Secondary;
|
||||
};
|
||||
Texture_Struct Slot[EQEmu::textures::materialCount];
|
||||
Texture_Struct Slot[EQEmu::textures::TextureCount];
|
||||
};
|
||||
|
||||
TextureProfile();
|
||||
@@ -1420,7 +1420,7 @@ struct LootingItem_Struct {
|
||||
/*002*/ uint32 looter;
|
||||
/*004*/ uint16 slot_id;
|
||||
/*006*/ uint8 unknown3[2];
|
||||
/*008*/ int32 auto_loot;
|
||||
/*008*/ uint32 auto_loot;
|
||||
};
|
||||
|
||||
struct GuildManageStatus_Struct{
|
||||
@@ -1657,7 +1657,8 @@ struct Merchant_Sell_Struct {
|
||||
/*004*/ uint32 playerid; // Player's entity id
|
||||
/*008*/ uint32 itemslot;
|
||||
uint32 unknown12;
|
||||
/*016*/ uint32 quantity;
|
||||
/*016*/ uint8 quantity; // Already sold
|
||||
/*017*/ uint8 Unknown016[3];
|
||||
/*020*/ uint32 price;
|
||||
};
|
||||
struct Merchant_Purchase_Struct {
|
||||
@@ -3228,11 +3229,6 @@ struct AnnoyingZoneUnknown_Struct {
|
||||
uint32 value; //always 4
|
||||
};
|
||||
|
||||
struct LoadSpellSet_Struct {
|
||||
uint32 spell[MAX_PP_MEMSPELL];
|
||||
uint32 unknown;
|
||||
};
|
||||
|
||||
struct ApplyPoison_Struct {
|
||||
uint32 inventorySlot;
|
||||
uint32 success;
|
||||
|
||||
+48
-59
@@ -29,7 +29,7 @@
|
||||
#include "../eq_packet_structs.h"
|
||||
#include "../misc_functions.h"
|
||||
#include "../string_util.h"
|
||||
#include "../item_instance.h"
|
||||
#include "../item.h"
|
||||
#include "uf_structs.h"
|
||||
#include "../rulesys.h"
|
||||
|
||||
@@ -43,7 +43,7 @@ namespace UF
|
||||
static OpcodeManager *opcodes = nullptr;
|
||||
static Strategy struct_strategy;
|
||||
|
||||
void SerializeItem(EQEmu::OutBuffer& ob, const EQEmu::ItemInstance *inst, int16 slot_id, uint8 depth);
|
||||
void SerializeItem(EQEmu::OutBuffer& ob, const ItemInst *inst, int16 slot_id, uint8 depth);
|
||||
|
||||
// server to client inventory location converters
|
||||
static inline uint32 ServerToUFSlot(uint32 serverSlot);
|
||||
@@ -62,9 +62,6 @@ namespace UF
|
||||
static inline CastingSlot ServerToUFCastingSlot(EQEmu::CastingSlot slot);
|
||||
static inline EQEmu::CastingSlot UFToServerCastingSlot(CastingSlot slot);
|
||||
|
||||
static inline int ServerToUFBuffSlot(int index);
|
||||
static inline int UFToServerBuffSlot(int index);
|
||||
|
||||
void Register(EQStreamIdentifier &into)
|
||||
{
|
||||
//create our opcode manager if we havent already
|
||||
@@ -380,8 +377,17 @@ namespace UF
|
||||
OUT(buff.spellid);
|
||||
OUT(buff.duration);
|
||||
OUT(buff.num_hits);
|
||||
uint16 buffslot = emu->slotid;
|
||||
if (buffslot >= 25 && buffslot < 37)
|
||||
{
|
||||
buffslot += 5;
|
||||
}
|
||||
else if (buffslot >= 37)
|
||||
{
|
||||
buffslot += 14;
|
||||
}
|
||||
// TODO: implement slot_data stuff
|
||||
eq->slotid = ServerToUFBuffSlot(emu->slotid);
|
||||
eq->slotid = buffslot;
|
||||
OUT(bufffade); // Live (October 2011) sends a 2 rather than 0 when a buff is created, but it doesn't seem to matter.
|
||||
|
||||
FINISH_ENCODE();
|
||||
@@ -401,9 +407,19 @@ namespace UF
|
||||
__packet->WriteUInt8(emu->all_buffs); // 1 = all buffs, 0 = 1 buff
|
||||
__packet->WriteUInt16(emu->count);
|
||||
|
||||
for (int i = 0; i < emu->count; ++i)
|
||||
for (uint16 i = 0; i < emu->count; ++i)
|
||||
{
|
||||
__packet->WriteUInt32(emu->type == 0 ? ServerToUFBuffSlot(emu->entries[i].buff_slot) : emu->entries[i].buff_slot);
|
||||
uint16 buffslot = emu->entries[i].buff_slot;
|
||||
if (emu->entries[i].buff_slot >= 25 && emu->entries[i].buff_slot < 37)
|
||||
{
|
||||
buffslot += 5;
|
||||
}
|
||||
else if (emu->entries[i].buff_slot >= 37)
|
||||
{
|
||||
buffslot += 14;
|
||||
}
|
||||
|
||||
__packet->WriteUInt32(buffslot);
|
||||
__packet->WriteUInt32(emu->entries[i].spell_id);
|
||||
__packet->WriteUInt32(emu->entries[i].tics_remaining);
|
||||
__packet->WriteUInt32(emu->entries[i].num_hits);
|
||||
@@ -527,7 +543,7 @@ namespace UF
|
||||
ob.write((const char*)&item_count, sizeof(uint32));
|
||||
|
||||
for (int index = 0; index < item_count; ++index, ++eq) {
|
||||
SerializeItem(ob, (const EQEmu::ItemInstance*)eq->inst, eq->slot_id, 0);
|
||||
SerializeItem(ob, (const ItemInst*)eq->inst, eq->slot_id, 0);
|
||||
if (ob.tellp() == last_pos)
|
||||
Log.Out(Logs::General, Logs::Netcode, "[STRUCTS] Serialization failed on item slot %d during OP_CharInventory. Item skipped.", eq->slot_id);
|
||||
|
||||
@@ -861,8 +877,8 @@ namespace UF
|
||||
// This next field is actually a float. There is a groundspawn in freeportwest (sack of money sitting on some barrels) which requires this
|
||||
// field to be set to (float)255.0 to appear at all, and also the size field below to be 5, to be the correct size. I think SoD has the same
|
||||
// issue.
|
||||
VARSTRUCT_ENCODE_TYPE(float, OutBuffer, emu->tilt_x); //X tilt
|
||||
VARSTRUCT_ENCODE_TYPE(float, OutBuffer, emu->tilt_y); //Y tilt
|
||||
VARSTRUCT_ENCODE_TYPE(float, OutBuffer, 0); //X tilt
|
||||
VARSTRUCT_ENCODE_TYPE(float, OutBuffer, 0); //Y tilt
|
||||
VARSTRUCT_ENCODE_TYPE(float, OutBuffer, emu->size != 0 && (float)emu->size < 5000.f ? (float)((float)emu->size / 100.0f) : 1.f ); // This appears to be the size field. Hackish logic because some PEQ DB items were corrupt.
|
||||
VARSTRUCT_ENCODE_TYPE(float, OutBuffer, emu->y);
|
||||
VARSTRUCT_ENCODE_TYPE(float, OutBuffer, emu->x);
|
||||
@@ -1279,7 +1295,7 @@ namespace UF
|
||||
|
||||
ob.write((const char*)__emu_buffer, 4);
|
||||
|
||||
SerializeItem(ob, (const EQEmu::ItemInstance*)int_struct->inst, int_struct->slot_id, 0);
|
||||
SerializeItem(ob, (const ItemInst*)int_struct->inst, int_struct->slot_id, 0);
|
||||
if (ob.tellp() == last_pos) {
|
||||
Log.Out(Logs::General, Logs::Netcode, "[STRUCTS] Serialization failed on item slot %d.", int_struct->slot_id);
|
||||
delete in;
|
||||
@@ -1803,7 +1819,7 @@ namespace UF
|
||||
OUT(hairstyle);
|
||||
OUT(beard);
|
||||
// OUT(unknown00178[10]);
|
||||
for (r = EQEmu::textures::textureBegin; r < EQEmu::textures::materialCount; r++) {
|
||||
for (r = EQEmu::textures::TextureBegin; r < EQEmu::textures::TextureCount; r++) {
|
||||
eq->equipment.Slot[r].Material = emu->item_material.Slot[r].Material;
|
||||
eq->equipment.Slot[r].Unknown1 = 0;
|
||||
eq->equipment.Slot[r].EliteMaterial = 0;
|
||||
@@ -2287,10 +2303,10 @@ namespace UF
|
||||
eq_cse->HairColor = emu_cse->HairColor;
|
||||
eq_cse->Face = emu_cse->Face;
|
||||
|
||||
for (int equip_index = EQEmu::textures::textureBegin; equip_index < EQEmu::textures::materialCount; equip_index++) {
|
||||
for (int equip_index = 0; equip_index < EQEmu::textures::TextureCount; equip_index++) {
|
||||
eq_cse->Equip[equip_index].Material = emu_cse->Equip[equip_index].Material;
|
||||
eq_cse->Equip[equip_index].Unknown1 = emu_cse->Equip[equip_index].Unknown1;
|
||||
eq_cse->Equip[equip_index].EliteMaterial = emu_cse->Equip[equip_index].EliteModel;
|
||||
eq_cse->Equip[equip_index].EliteMaterial = emu_cse->Equip[equip_index].EliteMaterial;
|
||||
eq_cse->Equip[equip_index].Color = emu_cse->Equip[equip_index].Color;
|
||||
}
|
||||
|
||||
@@ -2855,7 +2871,7 @@ namespace UF
|
||||
float SpawnSize = emu->size;
|
||||
if (!((emu->NPC == 0) || (emu->race <= 12) || (emu->race == 128) || (emu->race == 130) || (emu->race == 330) || (emu->race == 522)))
|
||||
{
|
||||
PacketSize -= (sizeof(structs::Texture_Struct) * EQEmu::textures::materialCount);
|
||||
PacketSize -= (sizeof(structs::Texture_Struct) * EQEmu::textures::TextureCount);
|
||||
|
||||
if (emu->size == 0)
|
||||
{
|
||||
@@ -3054,7 +3070,7 @@ namespace UF
|
||||
|
||||
if ((emu->NPC == 0) || (emu->race <= 12) || (emu->race == 128) || (emu->race == 130) || (emu->race == 330) || (emu->race == 522))
|
||||
{
|
||||
for (k = EQEmu::textures::textureBegin; k < EQEmu::textures::materialCount; ++k)
|
||||
for (k = EQEmu::textures::TextureBegin; k < EQEmu::textures::TextureCount; ++k)
|
||||
{
|
||||
{
|
||||
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, emu->equipment_tint.Slot[k].Color);
|
||||
@@ -3090,17 +3106,17 @@ namespace UF
|
||||
{
|
||||
structs::Texture_Struct *Equipment = (structs::Texture_Struct *)Buffer;
|
||||
|
||||
for (k = EQEmu::textures::textureBegin; k < EQEmu::textures::materialCount; k++) {
|
||||
for (k = EQEmu::textures::TextureBegin; k < EQEmu::textures::TextureCount; k++) {
|
||||
if (emu->equipment.Slot[k].Material > 99999) {
|
||||
Equipment[k].Material = 63;
|
||||
} else {
|
||||
Equipment[k].Material = emu->equipment.Slot[k].Material;
|
||||
}
|
||||
Equipment[k].Unknown1 = emu->equipment.Slot[k].Unknown1;
|
||||
Equipment[k].EliteMaterial = emu->equipment.Slot[k].EliteModel;
|
||||
Equipment[k].EliteMaterial = emu->equipment.Slot[k].EliteMaterial;
|
||||
}
|
||||
|
||||
Buffer += (sizeof(structs::Texture_Struct) * EQEmu::textures::materialCount);
|
||||
Buffer += (sizeof(structs::Texture_Struct) * EQEmu::textures::TextureCount);
|
||||
}
|
||||
if (strlen(emu->title))
|
||||
{
|
||||
@@ -3222,7 +3238,6 @@ namespace UF
|
||||
IN(buff.unknown003);
|
||||
IN(buff.spellid);
|
||||
IN(buff.duration);
|
||||
emu->slotid = UFToServerBuffSlot(eq->slotid);
|
||||
IN(slotid);
|
||||
IN(bufffade);
|
||||
|
||||
@@ -3236,7 +3251,7 @@ namespace UF
|
||||
DECODE_LENGTH_EXACT(structs::BuffRemoveRequest_Struct);
|
||||
SETUP_DIRECT_DECODE(BuffRemoveRequest_Struct, structs::BuffRemoveRequest_Struct);
|
||||
|
||||
emu->SlotID = UFToServerBuffSlot(eq->SlotID);
|
||||
emu->SlotID = (eq->SlotID < 30) ? eq->SlotID : (eq->SlotID - 5);
|
||||
|
||||
IN(EntityID);
|
||||
|
||||
@@ -3834,9 +3849,9 @@ namespace UF
|
||||
return NextItemInstSerialNumber;
|
||||
}
|
||||
|
||||
void SerializeItem(EQEmu::OutBuffer& ob, const EQEmu::ItemInstance *inst, int16 slot_id_in, uint8 depth)
|
||||
void SerializeItem(EQEmu::OutBuffer& ob, const ItemInst *inst, int16 slot_id_in, uint8 depth)
|
||||
{
|
||||
const EQEmu::ItemData *item = inst->GetUnscaledItem();
|
||||
const EQEmu::ItemBase *item = inst->GetUnscaledItem();
|
||||
|
||||
UF::structs::ItemSerializationHeader hdr;
|
||||
|
||||
@@ -3880,7 +3895,7 @@ namespace UF
|
||||
int ornamentationAugtype = RuleI(Character, OrnamentationAugmentType);
|
||||
uint16 ornaIcon = 0;
|
||||
if (inst->GetOrnamentationAug(ornamentationAugtype)) {
|
||||
const EQEmu::ItemData *aug_weap = inst->GetOrnamentationAug(ornamentationAugtype)->GetItem();
|
||||
const EQEmu::ItemBase *aug_weap = inst->GetOrnamentationAug(ornamentationAugtype)->GetItem();
|
||||
ornaIcon = aug_weap->Icon;
|
||||
|
||||
ob.write(aug_weap->IDFile, strlen(aug_weap->IDFile));
|
||||
@@ -4211,18 +4226,18 @@ namespace UF
|
||||
|
||||
ob.write((const char*)&subitem_count, sizeof(uint32));
|
||||
|
||||
for (uint32 index = EQEmu::inventory::containerBegin; index < EQEmu::inventory::ContainerCount; ++index) {
|
||||
EQEmu::ItemInstance* sub = inst->GetItem(index);
|
||||
for (uint32 index = SUB_INDEX_BEGIN; index < EQEmu::legacy::ITEM_CONTAINER_SIZE; ++index) {
|
||||
ItemInst* sub = inst->GetItem(index);
|
||||
if (!sub)
|
||||
continue;
|
||||
|
||||
int SubSlotNumber = INVALID_INDEX;
|
||||
if (slot_id_in >= EQEmu::legacy::GENERAL_BEGIN && slot_id_in <= EQEmu::legacy::GENERAL_END)
|
||||
SubSlotNumber = (((slot_id_in + 3) * EQEmu::inventory::ContainerCount) + index + 1);
|
||||
SubSlotNumber = (((slot_id_in + 3) * EQEmu::legacy::ITEM_CONTAINER_SIZE) + index + 1);
|
||||
else if (slot_id_in >= EQEmu::legacy::BANK_BEGIN && slot_id_in <= EQEmu::legacy::BANK_END)
|
||||
SubSlotNumber = (((slot_id_in - EQEmu::legacy::BANK_BEGIN) * EQEmu::inventory::ContainerCount) + EQEmu::legacy::BANK_BAGS_BEGIN + index);
|
||||
SubSlotNumber = (((slot_id_in - EQEmu::legacy::BANK_BEGIN) * EQEmu::legacy::ITEM_CONTAINER_SIZE) + EQEmu::legacy::BANK_BAGS_BEGIN + index);
|
||||
else if (slot_id_in >= EQEmu::legacy::SHARED_BANK_BEGIN && slot_id_in <= EQEmu::legacy::SHARED_BANK_END)
|
||||
SubSlotNumber = (((slot_id_in - EQEmu::legacy::SHARED_BANK_BEGIN) * EQEmu::inventory::ContainerCount) + EQEmu::legacy::SHARED_BANK_BAGS_BEGIN + index);
|
||||
SubSlotNumber = (((slot_id_in - EQEmu::legacy::SHARED_BANK_BEGIN) * EQEmu::legacy::ITEM_CONTAINER_SIZE) + EQEmu::legacy::SHARED_BANK_BAGS_BEGIN + index);
|
||||
else
|
||||
SubSlotNumber = slot_id_in;
|
||||
|
||||
@@ -4240,7 +4255,7 @@ namespace UF
|
||||
{
|
||||
uint32 UnderfootSlot = 0;
|
||||
|
||||
if (serverSlot >= EQEmu::inventory::slotAmmo && serverSlot <= 53) // Cursor/Ammo/Power Source and Normal Inventory Slots
|
||||
if (serverSlot >= EQEmu::legacy::SlotAmmo && serverSlot <= 53) // Cursor/Ammo/Power Source and Normal Inventory Slots
|
||||
UnderfootSlot = serverSlot + 1;
|
||||
else if (serverSlot >= EQEmu::legacy::GENERAL_BAGS_BEGIN && serverSlot <= EQEmu::legacy::CURSOR_BAG_END)
|
||||
UnderfootSlot = serverSlot + 11;
|
||||
@@ -4248,7 +4263,7 @@ namespace UF
|
||||
UnderfootSlot = serverSlot + 1;
|
||||
else if (serverSlot >= EQEmu::legacy::SHARED_BANK_BAGS_BEGIN && serverSlot <= EQEmu::legacy::SHARED_BANK_BAGS_END)
|
||||
UnderfootSlot = serverSlot + 1;
|
||||
else if (serverSlot == EQEmu::inventory::slotPowerSource)
|
||||
else if (serverSlot == EQEmu::legacy::SlotPowerSource)
|
||||
UnderfootSlot = invslot::PossessionsPowerSource;
|
||||
else
|
||||
UnderfootSlot = serverSlot;
|
||||
@@ -4275,7 +4290,7 @@ namespace UF
|
||||
else if (ufSlot >= invbag::SharedBankBagsBegin && ufSlot <= invbag::SharedBankBagsEnd)
|
||||
ServerSlot = ufSlot - 1;
|
||||
else if (ufSlot == invslot::PossessionsPowerSource)
|
||||
ServerSlot = EQEmu::inventory::slotPowerSource;
|
||||
ServerSlot = EQEmu::legacy::SlotPowerSource;
|
||||
else
|
||||
ServerSlot = ufSlot;
|
||||
|
||||
@@ -4440,30 +4455,4 @@ namespace UF
|
||||
return EQEmu::CastingSlot::Discipline;
|
||||
}
|
||||
}
|
||||
|
||||
static inline int ServerToUFBuffSlot(int index)
|
||||
{
|
||||
// we're a disc
|
||||
if (index >= EQEmu::constants::LongBuffs + EQEmu::constants::ShortBuffs)
|
||||
return index - EQEmu::constants::LongBuffs - EQEmu::constants::ShortBuffs +
|
||||
constants::LongBuffs + constants::ShortBuffs;
|
||||
// we're a song
|
||||
if (index >= EQEmu::constants::LongBuffs)
|
||||
return index - EQEmu::constants::LongBuffs + constants::LongBuffs;
|
||||
// we're a normal buff
|
||||
return index; // as long as we guard against bad slots server side, we should be fine
|
||||
}
|
||||
|
||||
static inline int UFToServerBuffSlot(int index)
|
||||
{
|
||||
// we're a disc
|
||||
if (index >= constants::LongBuffs + constants::ShortBuffs)
|
||||
return index - constants::LongBuffs - constants::ShortBuffs + EQEmu::constants::LongBuffs +
|
||||
EQEmu::constants::ShortBuffs;
|
||||
// we're a song
|
||||
if (index >= constants::LongBuffs)
|
||||
return index - constants::LongBuffs + EQEmu::constants::LongBuffs;
|
||||
// we're a normal buff
|
||||
return index; // as long as we guard against bad slots server side, we should be fine
|
||||
}
|
||||
} /*UF*/
|
||||
|
||||
+16
-24
@@ -64,7 +64,7 @@ namespace UF
|
||||
InvTypeOther,
|
||||
InvTypeCount
|
||||
};
|
||||
|
||||
|
||||
} /*invtype*/
|
||||
|
||||
namespace invslot {
|
||||
@@ -115,21 +115,21 @@ namespace UF
|
||||
const int GeneralBegin = PossessionsGeneral1;
|
||||
const int GeneralEnd = PossessionsGeneral8;
|
||||
const int GeneralCount = (GeneralEnd - GeneralBegin + 1);
|
||||
|
||||
|
||||
} /*invslot*/
|
||||
|
||||
namespace invbag {
|
||||
inline EQEmu::versions::ClientVersion GetInvBagRef() { return EQEmu::versions::ClientVersion::UF; }
|
||||
|
||||
enum : int { InvBagInvalid = -1, InvBagBegin };
|
||||
|
||||
|
||||
} /*invbag*/
|
||||
|
||||
namespace invaug {
|
||||
inline EQEmu::versions::ClientVersion GetInvAugRef() { return EQEmu::versions::ClientVersion::UF; }
|
||||
|
||||
enum : int { InvAugInvalid = -1, InvAugBegin };
|
||||
|
||||
|
||||
} /*invaug*/
|
||||
|
||||
namespace item {
|
||||
@@ -148,27 +148,27 @@ namespace UF
|
||||
ItemPacketCharmUpdate = 110,
|
||||
ItemPacket11 = 111
|
||||
};
|
||||
|
||||
|
||||
} /*item*/
|
||||
|
||||
namespace profile {
|
||||
inline EQEmu::versions::ClientVersion GetProfileRef() { return EQEmu::versions::ClientVersion::UF; }
|
||||
|
||||
|
||||
} /*profile*/
|
||||
|
||||
namespace constants {
|
||||
inline EQEmu::versions::ClientVersion GetConstantsRef() { return EQEmu::versions::ClientVersion::UF; }
|
||||
|
||||
|
||||
} /*constants*/
|
||||
|
||||
namespace behavior {
|
||||
inline EQEmu::versions::ClientVersion GetBehaviorRef() { return EQEmu::versions::ClientVersion::UF; }
|
||||
|
||||
|
||||
} /*behavior*/
|
||||
|
||||
namespace skills {
|
||||
inline EQEmu::versions::ClientVersion GetSkillsRef() { return EQEmu::versions::ClientVersion::UF; }
|
||||
|
||||
|
||||
} /*skills*/
|
||||
|
||||
|
||||
@@ -208,7 +208,7 @@ namespace UF
|
||||
extern const char* GetInvTypeName(int inv_type);
|
||||
|
||||
extern bool IsInvTypePersistent(int inv_type);
|
||||
|
||||
|
||||
} /*invtype*/
|
||||
|
||||
namespace invslot {
|
||||
@@ -237,7 +237,7 @@ namespace UF
|
||||
extern const char* GetInvPossessionsSlotName(int inv_slot);
|
||||
extern const char* GetInvCorpseSlotName(int inv_slot);
|
||||
extern const char* GetInvSlotName(int inv_type, int inv_slot);
|
||||
|
||||
|
||||
} /*invslot*/
|
||||
|
||||
namespace invbag {
|
||||
@@ -264,7 +264,7 @@ namespace UF
|
||||
const int TradeBagsEnd = (TradeBagsBegin + TradeBagsSize) - 1;
|
||||
|
||||
extern const char* GetInvBagIndexName(int bag_index);
|
||||
|
||||
|
||||
} /*invbag*/
|
||||
|
||||
namespace invaug {
|
||||
@@ -288,32 +288,24 @@ namespace UF
|
||||
const size_t PotionBeltSize = 5;
|
||||
|
||||
const size_t SkillArraySize = 100;
|
||||
|
||||
|
||||
} /*profile*/
|
||||
|
||||
namespace constants {
|
||||
const size_t CharacterCreationLimit = 12;
|
||||
|
||||
const size_t SayLinkBodySize = 50;
|
||||
|
||||
const int LongBuffs = 30;
|
||||
const int ShortBuffs = 20;
|
||||
const int DiscBuffs = 1;
|
||||
const int TotalBuffs = LongBuffs + ShortBuffs + DiscBuffs;
|
||||
const int NPCBuffs = 85;
|
||||
const int PetBuffs = NPCBuffs;
|
||||
const int MercBuffs = LongBuffs;
|
||||
|
||||
|
||||
} /*constants*/
|
||||
|
||||
namespace behavior {
|
||||
const bool CoinHasWeight = false;
|
||||
|
||||
|
||||
} /*behavior*/
|
||||
|
||||
namespace skills {
|
||||
const size_t LastUsableSkill = EQEmu::skills::SkillTripleAttack;
|
||||
|
||||
|
||||
} /*skills*/
|
||||
|
||||
}; /*UF*/
|
||||
|
||||
@@ -149,7 +149,7 @@ struct TintProfile
|
||||
Tint_Struct Primary;
|
||||
Tint_Struct Secondary;
|
||||
};
|
||||
Tint_Struct Slot[EQEmu::textures::materialCount];
|
||||
Tint_Struct Slot[EQEmu::textures::TextureCount];
|
||||
};
|
||||
};
|
||||
|
||||
@@ -178,7 +178,7 @@ struct TextureProfile
|
||||
Texture_Struct Primary;
|
||||
Texture_Struct Secondary;
|
||||
};
|
||||
Texture_Struct Slot[EQEmu::textures::materialCount];
|
||||
Texture_Struct Slot[EQEmu::textures::TextureCount];
|
||||
};
|
||||
|
||||
TextureProfile();
|
||||
@@ -195,7 +195,7 @@ struct CharacterSelectEntry_Struct
|
||||
/*0000*/ uint8 Beard; //
|
||||
/*0001*/ uint8 HairColor; //
|
||||
/*0000*/ uint8 Face; //
|
||||
/*0000*/ CharSelectEquip Equip[EQEmu::textures::materialCount];
|
||||
/*0000*/ CharSelectEquip Equip[EQEmu::textures::TextureCount];
|
||||
/*0000*/ uint32 PrimaryIDFile; //
|
||||
/*0000*/ uint32 SecondaryIDFile; //
|
||||
/*0000*/ uint8 Unknown15; // 0xff
|
||||
@@ -847,7 +847,7 @@ struct BindStruct {
|
||||
*/
|
||||
static const uint32 MAX_PP_LANGUAGE = 25; //
|
||||
static const uint32 MAX_PP_SPELLBOOK = 720; // Confirmed 60 pages on Underfoot now
|
||||
static const uint32 MAX_PP_MEMSPELL = 12; //was 9 now 10 on Underfoot
|
||||
static const uint32 MAX_PP_MEMSPELL = 10; //was 9 now 10 on Underfoot
|
||||
static const uint32 MAX_PP_SKILL = PACKET_SKILL_ARRAY_SIZE; // 100 - actual skills buffer size
|
||||
static const uint32 MAX_PP_AA_ARRAY = 300; //was 299
|
||||
static const uint32 MAX_GROUP_MEMBERS = 6;
|
||||
@@ -917,7 +917,7 @@ struct PlayerProfile_Struct
|
||||
/*00160*/ uint32 deity; // deity
|
||||
/*00164*/ uint32 intoxication; // Alcohol level (in ticks till sober?)
|
||||
/*00168*/ uint32 spellSlotRefresh[MAX_PP_MEMSPELL]; // Refresh time (millis) - 4 Octets Each
|
||||
/*00208*/ uint8 unknown00208[6]; // Seen 00 00 00 00 00 00 00 00 00 00 00 00 02 01
|
||||
/*00208*/ uint8 unknown00208[14]; // Seen 00 00 00 00 00 00 00 00 00 00 00 00 02 01
|
||||
/*00222*/ uint32 abilitySlotRefresh;
|
||||
/*00226*/ uint8 haircolor; // Player hair color
|
||||
/*00227*/ uint8 beardcolor; // Player beard color
|
||||
@@ -945,7 +945,7 @@ struct PlayerProfile_Struct
|
||||
/*04217*/ uint8 unknown04217[147]; // was [175]
|
||||
/*04364*/ uint32 spell_book[MAX_PP_SPELLBOOK]; // List of the Spells in spellbook 720 = 90 pages [2880] was [1920]
|
||||
/*07244*/ uint32 mem_spells[MAX_PP_MEMSPELL]; // List of spells memorized
|
||||
/*07284*/ uint8 unknown07284[20]; //#### uint8 unknown04396[32]; in Titanium ####[28]
|
||||
/*07284*/ uint8 unknown07284[28]; //#### uint8 unknown04396[32]; in Titanium ####[28]
|
||||
/*07312*/ uint32 platinum; // Platinum Pieces on player
|
||||
/*07316*/ uint32 gold; // Gold Pieces on player
|
||||
/*07320*/ uint32 silver; // Silver Pieces on player
|
||||
@@ -1707,7 +1707,7 @@ struct LootingItem_Struct {
|
||||
/*000*/ uint32 lootee;
|
||||
/*004*/ uint32 looter;
|
||||
/*008*/ uint32 slot_id;
|
||||
/*012*/ int32 auto_loot;
|
||||
/*012*/ uint32 auto_loot;
|
||||
/*016*/ uint32 unknown16;
|
||||
/*020*/
|
||||
};
|
||||
@@ -1921,7 +1921,8 @@ struct Merchant_Sell_Struct {
|
||||
/*004*/ uint32 playerid; // Player's entity id
|
||||
/*008*/ uint32 itemslot;
|
||||
/*012*/ uint32 unknown12;
|
||||
/*016*/ uint32 quantity;
|
||||
/*016*/ uint8 quantity; // Already sold
|
||||
/*017*/ uint8 Unknown017[3];
|
||||
/*020*/ uint32 Unknown020;
|
||||
/*024*/ uint32 price;
|
||||
/*028*/ uint32 pricehighorderbits; // It appears the price is 64 bits in Underfoot+
|
||||
@@ -2011,7 +2012,7 @@ struct AdventureLeaderboard_Struct
|
||||
/*struct Item_Shop_Struct {
|
||||
uint16 merchantid;
|
||||
uint8 itemtype;
|
||||
ItemData item;
|
||||
ItemBase item;
|
||||
uint8 iss_unknown001[6];
|
||||
};*/
|
||||
|
||||
@@ -3928,6 +3929,7 @@ struct AnnoyingZoneUnknown_Struct {
|
||||
|
||||
struct LoadSpellSet_Struct {
|
||||
uint8 spell[MAX_PP_MEMSPELL]; // 0 if no action
|
||||
uint16 unknown2; // is this two more spell gems?
|
||||
uint32 unknown; // there seems to be an extra field in this packet...
|
||||
};
|
||||
|
||||
|
||||
+1
-1
@@ -8,7 +8,7 @@ enum EQEmuExePlatform
|
||||
ExePlatformWorld,
|
||||
ExePlatformLogin,
|
||||
ExePlatformQueryServ,
|
||||
ExePlatformSocket_Server,
|
||||
ExePlatformWebInterface,
|
||||
ExePlatformUCS,
|
||||
ExePlatformLaunch,
|
||||
ExePlatformSharedMemory,
|
||||
|
||||
@@ -65,15 +65,6 @@ namespace EQEmu {
|
||||
return Real(0.0, 1.0) <= required;
|
||||
}
|
||||
|
||||
// same range as client's roll0
|
||||
// This is their main high level RNG function
|
||||
int Roll0(int max)
|
||||
{
|
||||
if (max - 1 > 0)
|
||||
return Int(0, max - 1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// std::shuffle requires a RNG engine passed to it, so lets provide a wrapper to use our engine
|
||||
template<typename RandomAccessIterator>
|
||||
void Shuffle(RandomAccessIterator first, RandomAccessIterator last)
|
||||
|
||||
@@ -0,0 +1,226 @@
|
||||
#ifndef RAPIDJSON_ALLOCATORS_H_
|
||||
#define RAPIDJSON_ALLOCATORS_H_
|
||||
|
||||
#include "rapidjson.h"
|
||||
|
||||
namespace rapidjson {
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Allocator
|
||||
|
||||
/*! \class rapidjson::Allocator
|
||||
\brief Concept for allocating, resizing and freeing memory block.
|
||||
|
||||
Note that Malloc() and Realloc() are non-static but Free() is static.
|
||||
|
||||
So if an allocator need to support Free(), it needs to put its pointer in
|
||||
the header of memory block.
|
||||
|
||||
\code
|
||||
concept Allocator {
|
||||
static const bool kNeedFree; //!< Whether this allocator needs to call Free().
|
||||
|
||||
// Allocate a memory block.
|
||||
// \param size of the memory block in bytes.
|
||||
// \returns pointer to the memory block.
|
||||
void* Malloc(size_t size);
|
||||
|
||||
// Resize a memory block.
|
||||
// \param originalPtr The pointer to current memory block. Null pointer is permitted.
|
||||
// \param originalSize The current size in bytes. (Design issue: since some allocator may not book-keep this, explicitly pass to it can save memory.)
|
||||
// \param newSize the new size in bytes.
|
||||
void* Realloc(void* originalPtr, size_t originalSize, size_t newSize);
|
||||
|
||||
// Free a memory block.
|
||||
// \param pointer to the memory block. Null pointer is permitted.
|
||||
static void Free(void *ptr);
|
||||
};
|
||||
\endcode
|
||||
*/
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// CrtAllocator
|
||||
|
||||
//! C-runtime library allocator.
|
||||
/*! This class is just wrapper for standard C library memory routines.
|
||||
\note implements Allocator concept
|
||||
*/
|
||||
class CrtAllocator {
|
||||
public:
|
||||
static const bool kNeedFree = true;
|
||||
void* Malloc(size_t size) { return malloc(size); }
|
||||
void* Realloc(void* originalPtr, size_t originalSize, size_t newSize) { (void)originalSize; return realloc(originalPtr, newSize); }
|
||||
static void Free(void *ptr) { free(ptr); }
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// MemoryPoolAllocator
|
||||
|
||||
//! Default memory allocator used by the parser and DOM.
|
||||
/*! This allocator allocate memory blocks from pre-allocated memory chunks.
|
||||
|
||||
It does not free memory blocks. And Realloc() only allocate new memory.
|
||||
|
||||
The memory chunks are allocated by BaseAllocator, which is CrtAllocator by default.
|
||||
|
||||
User may also supply a buffer as the first chunk.
|
||||
|
||||
If the user-buffer is full then additional chunks are allocated by BaseAllocator.
|
||||
|
||||
The user-buffer is not deallocated by this allocator.
|
||||
|
||||
\tparam BaseAllocator the allocator type for allocating memory chunks. Default is CrtAllocator.
|
||||
\note implements Allocator concept
|
||||
*/
|
||||
template <typename BaseAllocator = CrtAllocator>
|
||||
class MemoryPoolAllocator {
|
||||
public:
|
||||
static const bool kNeedFree = false; //!< Tell users that no need to call Free() with this allocator. (concept Allocator)
|
||||
|
||||
//! Constructor with chunkSize.
|
||||
/*! \param chunkSize The size of memory chunk. The default is kDefaultChunkSize.
|
||||
\param baseAllocator The allocator for allocating memory chunks.
|
||||
*/
|
||||
MemoryPoolAllocator(size_t chunkSize = kDefaultChunkCapacity, BaseAllocator* baseAllocator = 0) :
|
||||
chunkHead_(0), chunk_capacity_(chunkSize), userBuffer_(0), baseAllocator_(baseAllocator), ownBaseAllocator_(0)
|
||||
{
|
||||
if (!baseAllocator_)
|
||||
ownBaseAllocator_ = baseAllocator_ = new BaseAllocator();
|
||||
AddChunk(chunk_capacity_);
|
||||
}
|
||||
|
||||
//! Constructor with user-supplied buffer.
|
||||
/*! The user buffer will be used firstly. When it is full, memory pool allocates new chunk with chunk size.
|
||||
|
||||
The user buffer will not be deallocated when this allocator is destructed.
|
||||
|
||||
\param buffer User supplied buffer.
|
||||
\param size Size of the buffer in bytes. It must at least larger than sizeof(ChunkHeader).
|
||||
\param chunkSize The size of memory chunk. The default is kDefaultChunkSize.
|
||||
\param baseAllocator The allocator for allocating memory chunks.
|
||||
*/
|
||||
MemoryPoolAllocator(void *buffer, size_t size, size_t chunkSize = kDefaultChunkCapacity, BaseAllocator* baseAllocator = 0) :
|
||||
chunkHead_(0), chunk_capacity_(chunkSize), userBuffer_(buffer), baseAllocator_(baseAllocator), ownBaseAllocator_(0)
|
||||
{
|
||||
RAPIDJSON_ASSERT(buffer != 0);
|
||||
RAPIDJSON_ASSERT(size > sizeof(ChunkHeader));
|
||||
chunkHead_ = reinterpret_cast<ChunkHeader*>(buffer);
|
||||
chunkHead_->capacity = size - sizeof(ChunkHeader);
|
||||
chunkHead_->size = 0;
|
||||
chunkHead_->next = 0;
|
||||
}
|
||||
|
||||
//! Destructor.
|
||||
/*! This deallocates all memory chunks, excluding the user-supplied buffer.
|
||||
*/
|
||||
~MemoryPoolAllocator() {
|
||||
Clear();
|
||||
delete ownBaseAllocator_;
|
||||
}
|
||||
|
||||
//! Deallocates all memory chunks, excluding the user-supplied buffer.
|
||||
void Clear() {
|
||||
while(chunkHead_ != 0 && chunkHead_ != userBuffer_) {
|
||||
ChunkHeader* next = chunkHead_->next;
|
||||
baseAllocator_->Free(chunkHead_);
|
||||
chunkHead_ = next;
|
||||
}
|
||||
}
|
||||
|
||||
//! Computes the total capacity of allocated memory chunks.
|
||||
/*! \return total capacity in bytes.
|
||||
*/
|
||||
size_t Capacity() const {
|
||||
size_t capacity = 0;
|
||||
for (ChunkHeader* c = chunkHead_; c != 0; c = c->next)
|
||||
capacity += c->capacity;
|
||||
return capacity;
|
||||
}
|
||||
|
||||
//! Computes the memory blocks allocated.
|
||||
/*! \return total used bytes.
|
||||
*/
|
||||
size_t Size() const {
|
||||
size_t size = 0;
|
||||
for (ChunkHeader* c = chunkHead_; c != 0; c = c->next)
|
||||
size += c->size;
|
||||
return size;
|
||||
}
|
||||
|
||||
//! Allocates a memory block. (concept Allocator)
|
||||
void* Malloc(size_t size) {
|
||||
size = RAPIDJSON_ALIGN(size);
|
||||
if (chunkHead_->size + size > chunkHead_->capacity)
|
||||
AddChunk(chunk_capacity_ > size ? chunk_capacity_ : size);
|
||||
|
||||
void *buffer = reinterpret_cast<char *>(chunkHead_ + 1) + chunkHead_->size;
|
||||
chunkHead_->size += size;
|
||||
return buffer;
|
||||
}
|
||||
|
||||
//! Resizes a memory block (concept Allocator)
|
||||
void* Realloc(void* originalPtr, size_t originalSize, size_t newSize) {
|
||||
if (originalPtr == 0)
|
||||
return Malloc(newSize);
|
||||
|
||||
// Do not shrink if new size is smaller than original
|
||||
if (originalSize >= newSize)
|
||||
return originalPtr;
|
||||
|
||||
// Simply expand it if it is the last allocation and there is sufficient space
|
||||
if (originalPtr == (char *)(chunkHead_ + 1) + chunkHead_->size - originalSize) {
|
||||
size_t increment = static_cast<size_t>(newSize - originalSize);
|
||||
increment = RAPIDJSON_ALIGN(increment);
|
||||
if (chunkHead_->size + increment <= chunkHead_->capacity) {
|
||||
chunkHead_->size += increment;
|
||||
return originalPtr;
|
||||
}
|
||||
}
|
||||
|
||||
// Realloc process: allocate and copy memory, do not free original buffer.
|
||||
void* newBuffer = Malloc(newSize);
|
||||
RAPIDJSON_ASSERT(newBuffer != 0); // Do not handle out-of-memory explicitly.
|
||||
return memcpy(newBuffer, originalPtr, originalSize);
|
||||
}
|
||||
|
||||
//! Frees a memory block (concept Allocator)
|
||||
static void Free(void *ptr) { (void)ptr; } // Do nothing
|
||||
|
||||
private:
|
||||
//! Copy constructor is not permitted.
|
||||
MemoryPoolAllocator(const MemoryPoolAllocator& rhs) /* = delete */;
|
||||
//! Copy assignment operator is not permitted.
|
||||
MemoryPoolAllocator& operator=(const MemoryPoolAllocator& rhs) /* = delete */;
|
||||
|
||||
//! Creates a new chunk.
|
||||
/*! \param capacity Capacity of the chunk in bytes.
|
||||
*/
|
||||
void AddChunk(size_t capacity) {
|
||||
ChunkHeader* chunk = reinterpret_cast<ChunkHeader*>(baseAllocator_->Malloc(sizeof(ChunkHeader) + capacity));
|
||||
chunk->capacity = capacity;
|
||||
chunk->size = 0;
|
||||
chunk->next = chunkHead_;
|
||||
chunkHead_ = chunk;
|
||||
}
|
||||
|
||||
static const int kDefaultChunkCapacity = 64 * 1024; //!< Default chunk capacity.
|
||||
|
||||
//! Chunk header for perpending to each chunk.
|
||||
/*! Chunks are stored as a singly linked list.
|
||||
*/
|
||||
struct ChunkHeader {
|
||||
size_t capacity; //!< Capacity of the chunk in bytes (excluding the header itself).
|
||||
size_t size; //!< Current size of allocated memory in bytes.
|
||||
ChunkHeader *next; //!< Next chunk in the linked list.
|
||||
};
|
||||
|
||||
ChunkHeader *chunkHead_; //!< Head of the chunk linked-list. Only the head chunk serves allocation.
|
||||
size_t chunk_capacity_; //!< The minimum capacity of chunk when they are allocated.
|
||||
void *userBuffer_; //!< User supplied buffer.
|
||||
BaseAllocator* baseAllocator_; //!< base allocator for allocating memory chunks.
|
||||
BaseAllocator* ownBaseAllocator_; //!< base allocator created by this object.
|
||||
};
|
||||
|
||||
} // namespace rapidjson
|
||||
|
||||
#endif // RAPIDJSON_ENCODINGS_H_
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,270 @@
|
||||
#ifndef RAPIDJSON_ENCODEDSTREAM_H_
|
||||
#define RAPIDJSON_ENCODEDSTREAM_H_
|
||||
|
||||
#include "rapidjson.h"
|
||||
|
||||
#ifdef __GNUC__
|
||||
RAPIDJSON_DIAG_PUSH
|
||||
RAPIDJSON_DIAG_OFF(effc++)
|
||||
#endif
|
||||
|
||||
namespace rapidjson {
|
||||
|
||||
//! Input byte stream wrapper with a statically bound encoding.
|
||||
/*!
|
||||
\tparam Encoding The interpretation of encoding of the stream. Either UTF8, UTF16LE, UTF16BE, UTF32LE, UTF32BE.
|
||||
\tparam InputByteStream Type of input byte stream. For example, FileReadStream.
|
||||
*/
|
||||
template <typename Encoding, typename InputByteStream>
|
||||
class EncodedInputStream {
|
||||
RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1);
|
||||
public:
|
||||
typedef typename Encoding::Ch Ch;
|
||||
|
||||
EncodedInputStream(InputByteStream& is) : is_(is) {
|
||||
current_ = Encoding::TakeBOM(is_);
|
||||
}
|
||||
|
||||
Ch Peek() const { return current_; }
|
||||
Ch Take() { Ch c = current_; current_ = Encoding::Take(is_); return c; }
|
||||
size_t Tell() const { return is_.Tell(); }
|
||||
|
||||
// Not implemented
|
||||
void Put(Ch) { RAPIDJSON_ASSERT(false); }
|
||||
void Flush() { RAPIDJSON_ASSERT(false); }
|
||||
Ch* PutBegin() { RAPIDJSON_ASSERT(false); return 0; }
|
||||
size_t PutEnd(Ch*) { RAPIDJSON_ASSERT(false); return 0; }
|
||||
|
||||
private:
|
||||
EncodedInputStream(const EncodedInputStream&);
|
||||
EncodedInputStream& operator=(const EncodedInputStream&);
|
||||
|
||||
InputByteStream& is_;
|
||||
Ch current_;
|
||||
};
|
||||
|
||||
//! Output byte stream wrapper with statically bound encoding.
|
||||
/*!
|
||||
\tparam Encoding The interpretation of encoding of the stream. Either UTF8, UTF16LE, UTF16BE, UTF32LE, UTF32BE.
|
||||
\tparam InputByteStream Type of input byte stream. For example, FileWriteStream.
|
||||
*/
|
||||
template <typename Encoding, typename OutputByteStream>
|
||||
class EncodedOutputStream {
|
||||
RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1);
|
||||
public:
|
||||
typedef typename Encoding::Ch Ch;
|
||||
|
||||
EncodedOutputStream(OutputByteStream& os, bool putBOM = true) : os_(os) {
|
||||
if (putBOM)
|
||||
Encoding::PutBOM(os_);
|
||||
}
|
||||
|
||||
void Put(Ch c) { Encoding::Put(os_, c); }
|
||||
void Flush() { os_.Flush(); }
|
||||
|
||||
// Not implemented
|
||||
Ch Peek() const { RAPIDJSON_ASSERT(false); }
|
||||
Ch Take() { RAPIDJSON_ASSERT(false); }
|
||||
size_t Tell() const { RAPIDJSON_ASSERT(false); return 0; }
|
||||
Ch* PutBegin() { RAPIDJSON_ASSERT(false); return 0; }
|
||||
size_t PutEnd(Ch*) { RAPIDJSON_ASSERT(false); return 0; }
|
||||
|
||||
private:
|
||||
EncodedOutputStream(const EncodedOutputStream&);
|
||||
EncodedOutputStream& operator=(const EncodedOutputStream&);
|
||||
|
||||
OutputByteStream& os_;
|
||||
};
|
||||
|
||||
#define RAPIDJSON_ENCODINGS_FUNC(x) UTF8<Ch>::x, UTF16LE<Ch>::x, UTF16BE<Ch>::x, UTF32LE<Ch>::x, UTF32BE<Ch>::x
|
||||
|
||||
//! Input stream wrapper with dynamically bound encoding and automatic encoding detection.
|
||||
/*!
|
||||
\tparam CharType Type of character for reading.
|
||||
\tparam InputByteStream type of input byte stream to be wrapped.
|
||||
*/
|
||||
template <typename CharType, typename InputByteStream>
|
||||
class AutoUTFInputStream {
|
||||
RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1);
|
||||
public:
|
||||
typedef CharType Ch;
|
||||
|
||||
//! Constructor.
|
||||
/*!
|
||||
\param is input stream to be wrapped.
|
||||
\param type UTF encoding type if it is not detected from the stream.
|
||||
*/
|
||||
AutoUTFInputStream(InputByteStream& is, UTFType type = kUTF8) : is_(&is), type_(type), hasBOM_(false) {
|
||||
DetectType();
|
||||
static const TakeFunc f[] = { RAPIDJSON_ENCODINGS_FUNC(Take) };
|
||||
takeFunc_ = f[type_];
|
||||
current_ = takeFunc_(*is_);
|
||||
}
|
||||
|
||||
UTFType GetType() const { return type_; }
|
||||
bool HasBOM() const { return hasBOM_; }
|
||||
|
||||
Ch Peek() const { return current_; }
|
||||
Ch Take() { Ch c = current_; current_ = takeFunc_(*is_); return c; }
|
||||
size_t Tell() const { return is_->Tell(); }
|
||||
|
||||
// Not implemented
|
||||
void Put(Ch) { RAPIDJSON_ASSERT(false); }
|
||||
void Flush() { RAPIDJSON_ASSERT(false); }
|
||||
Ch* PutBegin() { RAPIDJSON_ASSERT(false); return 0; }
|
||||
size_t PutEnd(Ch*) { RAPIDJSON_ASSERT(false); return 0; }
|
||||
|
||||
private:
|
||||
AutoUTFInputStream(const AutoUTFInputStream&);
|
||||
AutoUTFInputStream& operator=(const AutoUTFInputStream&);
|
||||
|
||||
// Detect encoding type with BOM or RFC 4627
|
||||
void DetectType() {
|
||||
// BOM (Byte Order Mark):
|
||||
// 00 00 FE FF UTF-32BE
|
||||
// FF FE 00 00 UTF-32LE
|
||||
// FE FF UTF-16BE
|
||||
// FF FE UTF-16LE
|
||||
// EF BB BF UTF-8
|
||||
|
||||
const unsigned char* c = (const unsigned char *)is_->Peek4();
|
||||
if (!c)
|
||||
return;
|
||||
|
||||
unsigned bom = c[0] | (c[1] << 8) | (c[2] << 16) | (c[3] << 24);
|
||||
hasBOM_ = false;
|
||||
if (bom == 0xFFFE0000) { type_ = kUTF32BE; hasBOM_ = true; is_->Take(); is_->Take(); is_->Take(); is_->Take(); }
|
||||
else if (bom == 0x0000FEFF) { type_ = kUTF32LE; hasBOM_ = true; is_->Take(); is_->Take(); is_->Take(); is_->Take(); }
|
||||
else if ((bom & 0xFFFF) == 0xFFFE) { type_ = kUTF16BE; hasBOM_ = true; is_->Take(); is_->Take(); }
|
||||
else if ((bom & 0xFFFF) == 0xFEFF) { type_ = kUTF16LE; hasBOM_ = true; is_->Take(); is_->Take(); }
|
||||
else if ((bom & 0xFFFFFF) == 0xBFBBEF) { type_ = kUTF8; hasBOM_ = true; is_->Take(); is_->Take(); is_->Take(); }
|
||||
|
||||
// RFC 4627: Section 3
|
||||
// "Since the first two characters of a JSON text will always be ASCII
|
||||
// characters [RFC0020], it is possible to determine whether an octet
|
||||
// stream is UTF-8, UTF-16 (BE or LE), or UTF-32 (BE or LE) by looking
|
||||
// at the pattern of nulls in the first four octets."
|
||||
// 00 00 00 xx UTF-32BE
|
||||
// 00 xx 00 xx UTF-16BE
|
||||
// xx 00 00 00 UTF-32LE
|
||||
// xx 00 xx 00 UTF-16LE
|
||||
// xx xx xx xx UTF-8
|
||||
|
||||
if (!hasBOM_) {
|
||||
unsigned pattern = (c[0] ? 1 : 0) | (c[1] ? 2 : 0) | (c[2] ? 4 : 0) | (c[3] ? 8 : 0);
|
||||
switch (pattern) {
|
||||
case 0x08: type_ = kUTF32BE; break;
|
||||
case 0x0A: type_ = kUTF16BE; break;
|
||||
case 0x01: type_ = kUTF32LE; break;
|
||||
case 0x05: type_ = kUTF16LE; break;
|
||||
case 0x0F: type_ = kUTF8; break;
|
||||
default: break; // Use type defined by user.
|
||||
}
|
||||
}
|
||||
|
||||
// Runtime check whether the size of character type is sufficient. It only perform checks with assertion.
|
||||
switch (type_) {
|
||||
case kUTF8:
|
||||
// Do nothing
|
||||
break;
|
||||
case kUTF16LE:
|
||||
case kUTF16BE:
|
||||
RAPIDJSON_ASSERT(sizeof(Ch) >= 2);
|
||||
break;
|
||||
case kUTF32LE:
|
||||
case kUTF32BE:
|
||||
RAPIDJSON_ASSERT(sizeof(Ch) >= 4);
|
||||
break;
|
||||
default:
|
||||
RAPIDJSON_ASSERT(false); // Invalid type
|
||||
}
|
||||
}
|
||||
|
||||
typedef Ch (*TakeFunc)(InputByteStream& is);
|
||||
InputByteStream* is_;
|
||||
UTFType type_;
|
||||
Ch current_;
|
||||
TakeFunc takeFunc_;
|
||||
bool hasBOM_;
|
||||
};
|
||||
|
||||
//! Output stream wrapper with dynamically bound encoding and automatic encoding detection.
|
||||
/*!
|
||||
\tparam CharType Type of character for writing.
|
||||
\tparam InputByteStream type of output byte stream to be wrapped.
|
||||
*/
|
||||
template <typename CharType, typename OutputByteStream>
|
||||
class AutoUTFOutputStream {
|
||||
RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1);
|
||||
public:
|
||||
typedef CharType Ch;
|
||||
|
||||
//! Constructor.
|
||||
/*!
|
||||
\param os output stream to be wrapped.
|
||||
\param type UTF encoding type.
|
||||
\param putBOM Whether to write BOM at the beginning of the stream.
|
||||
*/
|
||||
AutoUTFOutputStream(OutputByteStream& os, UTFType type, bool putBOM) : os_(&os), type_(type) {
|
||||
// RUntime check whether the size of character type is sufficient. It only perform checks with assertion.
|
||||
switch (type_) {
|
||||
case kUTF16LE:
|
||||
case kUTF16BE:
|
||||
RAPIDJSON_ASSERT(sizeof(Ch) >= 2);
|
||||
break;
|
||||
case kUTF32LE:
|
||||
case kUTF32BE:
|
||||
RAPIDJSON_ASSERT(sizeof(Ch) >= 4);
|
||||
break;
|
||||
case kUTF8:
|
||||
// Do nothing
|
||||
break;
|
||||
default:
|
||||
RAPIDJSON_ASSERT(false); // Invalid UTFType
|
||||
}
|
||||
|
||||
static const PutFunc f[] = { RAPIDJSON_ENCODINGS_FUNC(Put) };
|
||||
putFunc_ = f[type_];
|
||||
|
||||
if (putBOM)
|
||||
PutBOM();
|
||||
}
|
||||
|
||||
UTFType GetType() const { return type_; }
|
||||
|
||||
void Put(Ch c) { putFunc_(*os_, c); }
|
||||
void Flush() { os_->Flush(); }
|
||||
|
||||
// Not implemented
|
||||
Ch Peek() const { RAPIDJSON_ASSERT(false); }
|
||||
Ch Take() { RAPIDJSON_ASSERT(false); }
|
||||
size_t Tell() const { RAPIDJSON_ASSERT(false); return 0; }
|
||||
Ch* PutBegin() { RAPIDJSON_ASSERT(false); return 0; }
|
||||
size_t PutEnd(Ch*) { RAPIDJSON_ASSERT(false); return 0; }
|
||||
|
||||
private:
|
||||
AutoUTFOutputStream(const AutoUTFOutputStream&);
|
||||
AutoUTFOutputStream& operator=(const AutoUTFOutputStream&);
|
||||
|
||||
void PutBOM() {
|
||||
typedef void (*PutBOMFunc)(OutputByteStream&);
|
||||
static const PutBOMFunc f[] = { RAPIDJSON_ENCODINGS_FUNC(PutBOM) };
|
||||
f[type_](*os_);
|
||||
}
|
||||
|
||||
typedef void (*PutFunc)(OutputByteStream&, Ch);
|
||||
|
||||
OutputByteStream* os_;
|
||||
UTFType type_;
|
||||
PutFunc putFunc_;
|
||||
};
|
||||
|
||||
#undef RAPIDJSON_ENCODINGS_FUNC
|
||||
|
||||
} // namespace rapidjson
|
||||
|
||||
#ifdef __GNUC__
|
||||
RAPIDJSON_DIAG_POP
|
||||
#endif
|
||||
|
||||
#endif // RAPIDJSON_FILESTREAM_H_
|
||||
@@ -0,0 +1,610 @@
|
||||
#ifndef RAPIDJSON_ENCODINGS_H_
|
||||
#define RAPIDJSON_ENCODINGS_H_
|
||||
|
||||
#include "rapidjson.h"
|
||||
|
||||
#ifdef _MSC_VER
|
||||
RAPIDJSON_DIAG_PUSH
|
||||
RAPIDJSON_DIAG_OFF(4244) // conversion from 'type1' to 'type2', possible loss of data
|
||||
RAPIDJSON_DIAG_OFF(4702) // unreachable code
|
||||
#elif defined(__GNUC__)
|
||||
RAPIDJSON_DIAG_PUSH
|
||||
RAPIDJSON_DIAG_OFF(effc++)
|
||||
#endif
|
||||
|
||||
namespace rapidjson {
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Encoding
|
||||
|
||||
/*! \class rapidjson::Encoding
|
||||
\brief Concept for encoding of Unicode characters.
|
||||
|
||||
\code
|
||||
concept Encoding {
|
||||
typename Ch; //! Type of character. A "character" is actually a code unit in unicode's definition.
|
||||
|
||||
enum { supportUnicode = 1 }; // or 0 if not supporting unicode
|
||||
|
||||
//! \brief Encode a Unicode codepoint to an output stream.
|
||||
//! \param os Output stream.
|
||||
//! \param codepoint An unicode codepoint, ranging from 0x0 to 0x10FFFF inclusively.
|
||||
template<typename OutputStream>
|
||||
static void Encode(OutputStream& os, unsigned codepoint);
|
||||
|
||||
//! \brief Decode a Unicode codepoint from an input stream.
|
||||
//! \param is Input stream.
|
||||
//! \param codepoint Output of the unicode codepoint.
|
||||
//! \return true if a valid codepoint can be decoded from the stream.
|
||||
template <typename InputStream>
|
||||
static bool Decode(InputStream& is, unsigned* codepoint);
|
||||
|
||||
//! \brief Validate one Unicode codepoint from an encoded stream.
|
||||
//! \param is Input stream to obtain codepoint.
|
||||
//! \param os Output for copying one codepoint.
|
||||
//! \return true if it is valid.
|
||||
//! \note This function just validating and copying the codepoint without actually decode it.
|
||||
template <typename InputStream, typename OutputStream>
|
||||
static bool Validate(InputStream& is, OutputStream& os);
|
||||
|
||||
// The following functions are deal with byte streams.
|
||||
|
||||
//! Take a character from input byte stream, skip BOM if exist.
|
||||
template <typename InputByteStream>
|
||||
static CharType TakeBOM(InputByteStream& is);
|
||||
|
||||
//! Take a character from input byte stream.
|
||||
template <typename InputByteStream>
|
||||
static Ch Take(InputByteStream& is);
|
||||
|
||||
//! Put BOM to output byte stream.
|
||||
template <typename OutputByteStream>
|
||||
static void PutBOM(OutputByteStream& os);
|
||||
|
||||
//! Put a character to output byte stream.
|
||||
template <typename OutputByteStream>
|
||||
static void Put(OutputByteStream& os, Ch c);
|
||||
};
|
||||
\endcode
|
||||
*/
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// UTF8
|
||||
|
||||
//! UTF-8 encoding.
|
||||
/*! http://en.wikipedia.org/wiki/UTF-8
|
||||
http://tools.ietf.org/html/rfc3629
|
||||
\tparam CharType Code unit for storing 8-bit UTF-8 data. Default is char.
|
||||
\note implements Encoding concept
|
||||
*/
|
||||
template<typename CharType = char>
|
||||
struct UTF8 {
|
||||
typedef CharType Ch;
|
||||
|
||||
enum { supportUnicode = 1 };
|
||||
|
||||
template<typename OutputStream>
|
||||
static void Encode(OutputStream& os, unsigned codepoint) {
|
||||
if (codepoint <= 0x7F)
|
||||
os.Put(static_cast<Ch>(codepoint & 0xFF));
|
||||
else if (codepoint <= 0x7FF) {
|
||||
os.Put(static_cast<Ch>(0xC0 | ((codepoint >> 6) & 0xFF)));
|
||||
os.Put(static_cast<Ch>(0x80 | ((codepoint & 0x3F))));
|
||||
}
|
||||
else if (codepoint <= 0xFFFF) {
|
||||
os.Put(static_cast<Ch>(0xE0 | ((codepoint >> 12) & 0xFF)));
|
||||
os.Put(static_cast<Ch>(0x80 | ((codepoint >> 6) & 0x3F)));
|
||||
os.Put(static_cast<Ch>(0x80 | (codepoint & 0x3F)));
|
||||
}
|
||||
else {
|
||||
RAPIDJSON_ASSERT(codepoint <= 0x10FFFF);
|
||||
os.Put(static_cast<Ch>(0xF0 | ((codepoint >> 18) & 0xFF)));
|
||||
os.Put(static_cast<Ch>(0x80 | ((codepoint >> 12) & 0x3F)));
|
||||
os.Put(static_cast<Ch>(0x80 | ((codepoint >> 6) & 0x3F)));
|
||||
os.Put(static_cast<Ch>(0x80 | (codepoint & 0x3F)));
|
||||
}
|
||||
}
|
||||
|
||||
template <typename InputStream>
|
||||
static bool Decode(InputStream& is, unsigned* codepoint) {
|
||||
#define COPY() c = is.Take(); *codepoint = (*codepoint << 6) | ((unsigned char)c & 0x3Fu)
|
||||
#define TRANS(mask) result &= ((GetRange((unsigned char)c) & mask) != 0)
|
||||
#define TAIL() COPY(); TRANS(0x70)
|
||||
Ch c = is.Take();
|
||||
if (!(c & 0x80)) {
|
||||
*codepoint = (unsigned char)c;
|
||||
return true;
|
||||
}
|
||||
|
||||
unsigned char type = GetRange((unsigned char)c);
|
||||
*codepoint = (0xFF >> type) & (unsigned char)c;
|
||||
bool result = true;
|
||||
switch (type) {
|
||||
case 2: TAIL(); return result;
|
||||
case 3: TAIL(); TAIL(); return result;
|
||||
case 4: COPY(); TRANS(0x50); TAIL(); return result;
|
||||
case 5: COPY(); TRANS(0x10); TAIL(); TAIL(); return result;
|
||||
case 6: TAIL(); TAIL(); TAIL(); return result;
|
||||
case 10: COPY(); TRANS(0x20); TAIL(); return result;
|
||||
case 11: COPY(); TRANS(0x60); TAIL(); TAIL(); return result;
|
||||
default: return false;
|
||||
}
|
||||
#undef COPY
|
||||
#undef TRANS
|
||||
#undef TAIL
|
||||
}
|
||||
|
||||
template <typename InputStream, typename OutputStream>
|
||||
static bool Validate(InputStream& is, OutputStream& os) {
|
||||
#define COPY() os.Put(c = is.Take())
|
||||
#define TRANS(mask) result &= ((GetRange((unsigned char)c) & mask) != 0)
|
||||
#define TAIL() COPY(); TRANS(0x70)
|
||||
Ch c;
|
||||
COPY();
|
||||
if (!(c & 0x80))
|
||||
return true;
|
||||
|
||||
bool result = true;
|
||||
switch (GetRange((unsigned char)c)) {
|
||||
case 2: TAIL(); return result;
|
||||
case 3: TAIL(); TAIL(); return result;
|
||||
case 4: COPY(); TRANS(0x50); TAIL(); return result;
|
||||
case 5: COPY(); TRANS(0x10); TAIL(); TAIL(); return result;
|
||||
case 6: TAIL(); TAIL(); TAIL(); return result;
|
||||
case 10: COPY(); TRANS(0x20); TAIL(); return result;
|
||||
case 11: COPY(); TRANS(0x60); TAIL(); TAIL(); return result;
|
||||
default: return false;
|
||||
}
|
||||
#undef COPY
|
||||
#undef TRANS
|
||||
#undef TAIL
|
||||
}
|
||||
|
||||
static unsigned char GetRange(unsigned char c) {
|
||||
// Referring to DFA of http://bjoern.hoehrmann.de/utf-8/decoder/dfa/
|
||||
// With new mapping 1 -> 0x10, 7 -> 0x20, 9 -> 0x40, such that AND operation can test multiple types.
|
||||
static const unsigned char type[] = {
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,
|
||||
0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,
|
||||
0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,
|
||||
0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,
|
||||
8,8,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
|
||||
10,3,3,3,3,3,3,3,3,3,3,3,3,4,3,3, 11,6,6,6,5,8,8,8,8,8,8,8,8,8,8,8,
|
||||
};
|
||||
return type[c];
|
||||
}
|
||||
|
||||
template <typename InputByteStream>
|
||||
static CharType TakeBOM(InputByteStream& is) {
|
||||
RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1);
|
||||
Ch c = Take(is);
|
||||
if ((unsigned char)c != 0xEFu) return c;
|
||||
c = is.Take();
|
||||
if ((unsigned char)c != 0xBBu) return c;
|
||||
c = is.Take();
|
||||
if ((unsigned char)c != 0xBFu) return c;
|
||||
c = is.Take();
|
||||
return c;
|
||||
}
|
||||
|
||||
template <typename InputByteStream>
|
||||
static Ch Take(InputByteStream& is) {
|
||||
RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1);
|
||||
return is.Take();
|
||||
}
|
||||
|
||||
template <typename OutputByteStream>
|
||||
static void PutBOM(OutputByteStream& os) {
|
||||
RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1);
|
||||
os.Put(0xEFu); os.Put(0xBBu); os.Put(0xBFu);
|
||||
}
|
||||
|
||||
template <typename OutputByteStream>
|
||||
static void Put(OutputByteStream& os, Ch c) {
|
||||
RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1);
|
||||
os.Put(static_cast<typename OutputByteStream::Ch>(c));
|
||||
}
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// UTF16
|
||||
|
||||
//! UTF-16 encoding.
|
||||
/*! http://en.wikipedia.org/wiki/UTF-16
|
||||
http://tools.ietf.org/html/rfc2781
|
||||
\tparam CharType Type for storing 16-bit UTF-16 data. Default is wchar_t. C++11 may use char16_t instead.
|
||||
\note implements Encoding concept
|
||||
|
||||
\note For in-memory access, no need to concern endianness. The code units and code points are represented by CPU's endianness.
|
||||
For streaming, use UTF16LE and UTF16BE, which handle endianness.
|
||||
*/
|
||||
template<typename CharType = wchar_t>
|
||||
struct UTF16 {
|
||||
typedef CharType Ch;
|
||||
RAPIDJSON_STATIC_ASSERT(sizeof(Ch) >= 2);
|
||||
|
||||
enum { supportUnicode = 1 };
|
||||
|
||||
template<typename OutputStream>
|
||||
static void Encode(OutputStream& os, unsigned codepoint) {
|
||||
RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputStream::Ch) >= 2);
|
||||
if (codepoint <= 0xFFFF) {
|
||||
RAPIDJSON_ASSERT(codepoint < 0xD800 || codepoint > 0xDFFF); // Code point itself cannot be surrogate pair
|
||||
os.Put(static_cast<typename OutputStream::Ch>(codepoint));
|
||||
}
|
||||
else {
|
||||
RAPIDJSON_ASSERT(codepoint <= 0x10FFFF);
|
||||
unsigned v = codepoint - 0x10000;
|
||||
os.Put(static_cast<typename OutputStream::Ch>((v >> 10) | 0xD800));
|
||||
os.Put((v & 0x3FF) | 0xDC00);
|
||||
}
|
||||
}
|
||||
|
||||
template <typename InputStream>
|
||||
static bool Decode(InputStream& is, unsigned* codepoint) {
|
||||
RAPIDJSON_STATIC_ASSERT(sizeof(typename InputStream::Ch) >= 2);
|
||||
Ch c = is.Take();
|
||||
if (c < 0xD800 || c > 0xDFFF) {
|
||||
*codepoint = c;
|
||||
return true;
|
||||
}
|
||||
else if (c <= 0xDBFF) {
|
||||
*codepoint = (c & 0x3FF) << 10;
|
||||
c = is.Take();
|
||||
*codepoint |= (c & 0x3FF);
|
||||
*codepoint += 0x10000;
|
||||
return c >= 0xDC00 && c <= 0xDFFF;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
template <typename InputStream, typename OutputStream>
|
||||
static bool Validate(InputStream& is, OutputStream& os) {
|
||||
RAPIDJSON_STATIC_ASSERT(sizeof(typename InputStream::Ch) >= 2);
|
||||
RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputStream::Ch) >= 2);
|
||||
Ch c;
|
||||
os.Put(c = is.Take());
|
||||
if (c < 0xD800 || c > 0xDFFF)
|
||||
return true;
|
||||
else if (c <= 0xDBFF) {
|
||||
os.Put(c = is.Take());
|
||||
return c >= 0xDC00 && c <= 0xDFFF;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
//! UTF-16 little endian encoding.
|
||||
template<typename CharType = wchar_t>
|
||||
struct UTF16LE : UTF16<CharType> {
|
||||
template <typename InputByteStream>
|
||||
static CharType TakeBOM(InputByteStream& is) {
|
||||
RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1);
|
||||
CharType c = Take(is);
|
||||
return (unsigned short)c == 0xFEFFu ? Take(is) : c;
|
||||
}
|
||||
|
||||
template <typename InputByteStream>
|
||||
static CharType Take(InputByteStream& is) {
|
||||
RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1);
|
||||
CharType c = (unsigned char)is.Take();
|
||||
c |= (unsigned char)is.Take() << 8;
|
||||
return c;
|
||||
}
|
||||
|
||||
template <typename OutputByteStream>
|
||||
static void PutBOM(OutputByteStream& os) {
|
||||
RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1);
|
||||
os.Put(0xFFu); os.Put(0xFEu);
|
||||
}
|
||||
|
||||
template <typename OutputByteStream>
|
||||
static void Put(OutputByteStream& os, CharType c) {
|
||||
RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1);
|
||||
os.Put(c & 0xFFu);
|
||||
os.Put((c >> 8) & 0xFFu);
|
||||
}
|
||||
};
|
||||
|
||||
//! UTF-16 big endian encoding.
|
||||
template<typename CharType = wchar_t>
|
||||
struct UTF16BE : UTF16<CharType> {
|
||||
template <typename InputByteStream>
|
||||
static CharType TakeBOM(InputByteStream& is) {
|
||||
RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1);
|
||||
CharType c = Take(is);
|
||||
return (unsigned short)c == 0xFEFFu ? Take(is) : c;
|
||||
}
|
||||
|
||||
template <typename InputByteStream>
|
||||
static CharType Take(InputByteStream& is) {
|
||||
RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1);
|
||||
CharType c = (unsigned char)is.Take() << 8;
|
||||
c |= (unsigned char)is.Take();
|
||||
return c;
|
||||
}
|
||||
|
||||
template <typename OutputByteStream>
|
||||
static void PutBOM(OutputByteStream& os) {
|
||||
RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1);
|
||||
os.Put(0xFEu); os.Put(0xFFu);
|
||||
}
|
||||
|
||||
template <typename OutputByteStream>
|
||||
static void Put(OutputByteStream& os, CharType c) {
|
||||
RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1);
|
||||
os.Put((c >> 8) & 0xFFu);
|
||||
os.Put(c & 0xFFu);
|
||||
}
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// UTF32
|
||||
|
||||
//! UTF-32 encoding.
|
||||
/*! http://en.wikipedia.org/wiki/UTF-32
|
||||
\tparam CharType Type for storing 32-bit UTF-32 data. Default is unsigned. C++11 may use char32_t instead.
|
||||
\note implements Encoding concept
|
||||
|
||||
\note For in-memory access, no need to concern endianness. The code units and code points are represented by CPU's endianness.
|
||||
For streaming, use UTF32LE and UTF32BE, which handle endianness.
|
||||
*/
|
||||
template<typename CharType = unsigned>
|
||||
struct UTF32 {
|
||||
typedef CharType Ch;
|
||||
RAPIDJSON_STATIC_ASSERT(sizeof(Ch) >= 4);
|
||||
|
||||
enum { supportUnicode = 1 };
|
||||
|
||||
template<typename OutputStream>
|
||||
static void Encode(OutputStream& os, unsigned codepoint) {
|
||||
RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputStream::Ch) >= 4);
|
||||
RAPIDJSON_ASSERT(codepoint <= 0x10FFFF);
|
||||
os.Put(codepoint);
|
||||
}
|
||||
|
||||
template <typename InputStream>
|
||||
static bool Decode(InputStream& is, unsigned* codepoint) {
|
||||
RAPIDJSON_STATIC_ASSERT(sizeof(typename InputStream::Ch) >= 4);
|
||||
Ch c = is.Take();
|
||||
*codepoint = c;
|
||||
return c <= 0x10FFFF;
|
||||
}
|
||||
|
||||
template <typename InputStream, typename OutputStream>
|
||||
static bool Validate(InputStream& is, OutputStream& os) {
|
||||
RAPIDJSON_STATIC_ASSERT(sizeof(typename InputStream::Ch) >= 4);
|
||||
Ch c;
|
||||
os.Put(c = is.Take());
|
||||
return c <= 0x10FFFF;
|
||||
}
|
||||
};
|
||||
|
||||
//! UTF-32 little endian enocoding.
|
||||
template<typename CharType = unsigned>
|
||||
struct UTF32LE : UTF32<CharType> {
|
||||
template <typename InputByteStream>
|
||||
static CharType TakeBOM(InputByteStream& is) {
|
||||
RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1);
|
||||
CharType c = Take(is);
|
||||
return (unsigned)c == 0x0000FEFFu ? Take(is) : c;
|
||||
}
|
||||
|
||||
template <typename InputByteStream>
|
||||
static CharType Take(InputByteStream& is) {
|
||||
RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1);
|
||||
CharType c = (unsigned char)is.Take();
|
||||
c |= (unsigned char)is.Take() << 8;
|
||||
c |= (unsigned char)is.Take() << 16;
|
||||
c |= (unsigned char)is.Take() << 24;
|
||||
return c;
|
||||
}
|
||||
|
||||
template <typename OutputByteStream>
|
||||
static void PutBOM(OutputByteStream& os) {
|
||||
RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1);
|
||||
os.Put(0xFFu); os.Put(0xFEu); os.Put(0x00u); os.Put(0x00u);
|
||||
}
|
||||
|
||||
template <typename OutputByteStream>
|
||||
static void Put(OutputByteStream& os, CharType c) {
|
||||
RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1);
|
||||
os.Put(c & 0xFFu);
|
||||
os.Put((c >> 8) & 0xFFu);
|
||||
os.Put((c >> 16) & 0xFFu);
|
||||
os.Put((c >> 24) & 0xFFu);
|
||||
}
|
||||
};
|
||||
|
||||
//! UTF-32 big endian encoding.
|
||||
template<typename CharType = unsigned>
|
||||
struct UTF32BE : UTF32<CharType> {
|
||||
template <typename InputByteStream>
|
||||
static CharType TakeBOM(InputByteStream& is) {
|
||||
RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1);
|
||||
CharType c = Take(is);
|
||||
return (unsigned)c == 0x0000FEFFu ? Take(is) : c;
|
||||
}
|
||||
|
||||
template <typename InputByteStream>
|
||||
static CharType Take(InputByteStream& is) {
|
||||
RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1);
|
||||
CharType c = (unsigned char)is.Take() << 24;
|
||||
c |= (unsigned char)is.Take() << 16;
|
||||
c |= (unsigned char)is.Take() << 8;
|
||||
c |= (unsigned char)is.Take();
|
||||
return c;
|
||||
}
|
||||
|
||||
template <typename OutputByteStream>
|
||||
static void PutBOM(OutputByteStream& os) {
|
||||
RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1);
|
||||
os.Put(0x00u); os.Put(0x00u); os.Put(0xFEu); os.Put(0xFFu);
|
||||
}
|
||||
|
||||
template <typename OutputByteStream>
|
||||
static void Put(OutputByteStream& os, CharType c) {
|
||||
RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1);
|
||||
os.Put((c >> 24) & 0xFFu);
|
||||
os.Put((c >> 16) & 0xFFu);
|
||||
os.Put((c >> 8) & 0xFFu);
|
||||
os.Put(c & 0xFFu);
|
||||
}
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// ASCII
|
||||
|
||||
//! ASCII encoding.
|
||||
/*! http://en.wikipedia.org/wiki/ASCII
|
||||
\tparam CharType Code unit for storing 7-bit ASCII data. Default is char.
|
||||
\note implements Encoding concept
|
||||
*/
|
||||
template<typename CharType = char>
|
||||
struct ASCII {
|
||||
typedef CharType Ch;
|
||||
|
||||
enum { supportUnicode = 0 };
|
||||
|
||||
template<typename OutputStream>
|
||||
static void Encode(OutputStream& os, unsigned codepoint) {
|
||||
RAPIDJSON_ASSERT(codepoint <= 0x7F);
|
||||
os.Put(static_cast<Ch>(codepoint & 0xFF));
|
||||
}
|
||||
|
||||
template <typename InputStream>
|
||||
static bool Decode(InputStream& is, unsigned* codepoint) {
|
||||
unsigned char c = static_cast<unsigned char>(is.Take());
|
||||
*codepoint = c;
|
||||
return c <= 0X7F;
|
||||
}
|
||||
|
||||
template <typename InputStream, typename OutputStream>
|
||||
static bool Validate(InputStream& is, OutputStream& os) {
|
||||
unsigned char c = is.Take();
|
||||
os.Put(c);
|
||||
return c <= 0x7F;
|
||||
}
|
||||
|
||||
template <typename InputByteStream>
|
||||
static CharType TakeBOM(InputByteStream& is) {
|
||||
RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1);
|
||||
Ch c = Take(is);
|
||||
return c;
|
||||
}
|
||||
|
||||
template <typename InputByteStream>
|
||||
static Ch Take(InputByteStream& is) {
|
||||
RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1);
|
||||
return is.Take();
|
||||
}
|
||||
|
||||
template <typename OutputByteStream>
|
||||
static void PutBOM(OutputByteStream& os) {
|
||||
RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1);
|
||||
(void)os;
|
||||
}
|
||||
|
||||
template <typename OutputByteStream>
|
||||
static void Put(OutputByteStream& os, Ch c) {
|
||||
RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1);
|
||||
os.Put(static_cast<typename OutputByteStream::Ch>(c));
|
||||
}
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// AutoUTF
|
||||
|
||||
//! Runtime-specified UTF encoding type of a stream.
|
||||
enum UTFType {
|
||||
kUTF8 = 0, //!< UTF-8.
|
||||
kUTF16LE = 1, //!< UTF-16 little endian.
|
||||
kUTF16BE = 2, //!< UTF-16 big endian.
|
||||
kUTF32LE = 3, //!< UTF-32 little endian.
|
||||
kUTF32BE = 4 //!< UTF-32 big endian.
|
||||
};
|
||||
|
||||
//! Dynamically select encoding according to stream's runtime-specified UTF encoding type.
|
||||
/*! \note This class can be used with AutoUTFInputtStream and AutoUTFOutputStream, which provides GetType().
|
||||
*/
|
||||
template<typename CharType>
|
||||
struct AutoUTF {
|
||||
typedef CharType Ch;
|
||||
|
||||
enum { supportUnicode = 1 };
|
||||
|
||||
#define RAPIDJSON_ENCODINGS_FUNC(x) UTF8<Ch>::x, UTF16LE<Ch>::x, UTF16BE<Ch>::x, UTF32LE<Ch>::x, UTF32BE<Ch>::x
|
||||
|
||||
template<typename OutputStream>
|
||||
RAPIDJSON_FORCEINLINE static void Encode(OutputStream& os, unsigned codepoint) {
|
||||
typedef void (*EncodeFunc)(OutputStream&, unsigned);
|
||||
static const EncodeFunc f[] = { RAPIDJSON_ENCODINGS_FUNC(Encode) };
|
||||
(*f[os.GetType()])(os, codepoint);
|
||||
}
|
||||
|
||||
template <typename InputStream>
|
||||
RAPIDJSON_FORCEINLINE static bool Decode(InputStream& is, unsigned* codepoint) {
|
||||
typedef bool (*DecodeFunc)(InputStream&, unsigned*);
|
||||
static const DecodeFunc f[] = { RAPIDJSON_ENCODINGS_FUNC(Decode) };
|
||||
return (*f[is.GetType()])(is, codepoint);
|
||||
}
|
||||
|
||||
template <typename InputStream, typename OutputStream>
|
||||
RAPIDJSON_FORCEINLINE static bool Validate(InputStream& is, OutputStream& os) {
|
||||
typedef bool (*ValidateFunc)(InputStream&, OutputStream&);
|
||||
static const ValidateFunc f[] = { RAPIDJSON_ENCODINGS_FUNC(Validate) };
|
||||
return (*f[is.GetType()])(is, os);
|
||||
}
|
||||
|
||||
#undef RAPIDJSON_ENCODINGS_FUNC
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Transcoder
|
||||
|
||||
//! Encoding conversion.
|
||||
template<typename SourceEncoding, typename TargetEncoding>
|
||||
struct Transcoder {
|
||||
//! Take one Unicode codepoint from source encoding, convert it to target encoding and put it to the output stream.
|
||||
template<typename InputStream, typename OutputStream>
|
||||
RAPIDJSON_FORCEINLINE static bool Transcode(InputStream& is, OutputStream& os) {
|
||||
unsigned codepoint;
|
||||
if (!SourceEncoding::Decode(is, &codepoint))
|
||||
return false;
|
||||
TargetEncoding::Encode(os, codepoint);
|
||||
return true;
|
||||
}
|
||||
|
||||
//! Validate one Unicode codepoint from an encoded stream.
|
||||
template<typename InputStream, typename OutputStream>
|
||||
RAPIDJSON_FORCEINLINE static bool Validate(InputStream& is, OutputStream& os) {
|
||||
return Transcode(is, os); // Since source/target encoding is different, must transcode.
|
||||
}
|
||||
};
|
||||
|
||||
//! Specialization of Transcoder with same source and target encoding.
|
||||
template<typename Encoding>
|
||||
struct Transcoder<Encoding, Encoding> {
|
||||
template<typename InputStream, typename OutputStream>
|
||||
RAPIDJSON_FORCEINLINE static bool Transcode(InputStream& is, OutputStream& os) {
|
||||
os.Put(is.Take()); // Just copy one code unit. This semantic is different from primary template class.
|
||||
return true;
|
||||
}
|
||||
|
||||
template<typename InputStream, typename OutputStream>
|
||||
RAPIDJSON_FORCEINLINE static bool Validate(InputStream& is, OutputStream& os) {
|
||||
return Encoding::Validate(is, os); // source/target encoding are the same
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace rapidjson
|
||||
|
||||
#if defined(__GNUC__) || defined(_MSV_VER)
|
||||
RAPIDJSON_DIAG_POP
|
||||
#endif
|
||||
|
||||
#endif // RAPIDJSON_ENCODINGS_H_
|
||||
@@ -0,0 +1,52 @@
|
||||
#ifndef RAPIDJSON_ERROR_EN_H__
|
||||
#define RAPIDJSON_ERROR_EN_H__
|
||||
|
||||
#include "error.h"
|
||||
|
||||
namespace rapidjson {
|
||||
|
||||
//! Maps error code of parsing into error message.
|
||||
/*!
|
||||
\param parseErrorCode Error code obtained in parsing.
|
||||
\return the error message.
|
||||
\note User can make a copy of this function for localization.
|
||||
Using switch-case is safer for future modification of error codes.
|
||||
*/
|
||||
inline const RAPIDJSON_ERROR_CHARTYPE* GetParseError_En(ParseErrorCode parseErrorCode) {
|
||||
switch (parseErrorCode) {
|
||||
case kParseErrorNone: return RAPIDJSON_ERROR_STRING("No error.");
|
||||
|
||||
case kParseErrorDocumentEmpty: return RAPIDJSON_ERROR_STRING("The document is empty.");
|
||||
case kParseErrorDocumentRootNotObjectOrArray: return RAPIDJSON_ERROR_STRING("The document root must be either object or array.");
|
||||
case kParseErrorDocumentRootNotSingular: return RAPIDJSON_ERROR_STRING("The document root must not follow by other values.");
|
||||
|
||||
case kParseErrorValueInvalid: return RAPIDJSON_ERROR_STRING("Invalid value.");
|
||||
|
||||
case kParseErrorObjectMissName: return RAPIDJSON_ERROR_STRING("Missing a name for object member.");
|
||||
case kParseErrorObjectMissColon: return RAPIDJSON_ERROR_STRING("Missing a colon after a name of object member.");
|
||||
case kParseErrorObjectMissCommaOrCurlyBracket: return RAPIDJSON_ERROR_STRING("Missing a comma or '}' after an object member.");
|
||||
|
||||
case kParseErrorArrayMissCommaOrSquareBracket: return RAPIDJSON_ERROR_STRING("Missing a comma or ']' after an array element.");
|
||||
|
||||
case kParseErrorStringUnicodeEscapeInvalidHex: return RAPIDJSON_ERROR_STRING("Incorrect hex digit after \\u escape in string.");
|
||||
case kParseErrorStringUnicodeSurrogateInvalid: return RAPIDJSON_ERROR_STRING("The surrogate pair in string is invalid.");
|
||||
case kParseErrorStringEscapeInvalid: return RAPIDJSON_ERROR_STRING("Invalid escape character in string.");
|
||||
case kParseErrorStringMissQuotationMark: return RAPIDJSON_ERROR_STRING("Missing a closing quotation mark in string.");
|
||||
case kParseErrorStringInvalidEncoding: return RAPIDJSON_ERROR_STRING("Invalid encoding in string.");
|
||||
|
||||
case kParseErrorNumberTooBig: return RAPIDJSON_ERROR_STRING("Number too big to be stored in double.");
|
||||
case kParseErrorNumberMissFraction: return RAPIDJSON_ERROR_STRING("Miss fraction part in number.");
|
||||
case kParseErrorNumberMissExponent: return RAPIDJSON_ERROR_STRING("Miss exponent in number.");
|
||||
|
||||
case kParseErrorTermination: return RAPIDJSON_ERROR_STRING("Terminate parsing due to Handler error.");
|
||||
case kParseErrorUnspecificSyntaxError: return RAPIDJSON_ERROR_STRING("Unspecific syntax error.");
|
||||
case kParseErrorStackSizeLimitExceeded: return RAPIDJSON_ERROR_STRING("Parsing stack size limit is exceeded.");
|
||||
|
||||
default:
|
||||
return RAPIDJSON_ERROR_STRING("Unknown error.");
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace rapidjson
|
||||
|
||||
#endif // RAPIDJSON_ERROR_EN_H__
|
||||
@@ -0,0 +1,124 @@
|
||||
#ifndef RAPIDJSON_ERROR_ERROR_H__
|
||||
#define RAPIDJSON_ERROR_ERROR_H__
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// RAPIDJSON_ERROR_CHARTYPE
|
||||
|
||||
//! Character type of error messages.
|
||||
/*! The default charater type is char.
|
||||
On Windows, user can define this macro as TCHAR for supporting both
|
||||
unicode/non-unicode settings.
|
||||
*/
|
||||
#ifndef RAPIDJSON_ERROR_CHARTYPE
|
||||
#define RAPIDJSON_ERROR_CHARTYPE char
|
||||
#endif
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// RAPIDJSON_ERROR_STRING
|
||||
|
||||
//! Macro for converting string literial to RAPIDJSON_ERROR_CHARTYPE[].
|
||||
/*! By default this conversion macro does nothing.
|
||||
On Windows, user can define this macro as _T(x) for supporting both
|
||||
unicode/non-unicode settings.
|
||||
*/
|
||||
#ifndef RAPIDJSON_ERROR_STRING
|
||||
#define RAPIDJSON_ERROR_STRING(x) x
|
||||
#endif
|
||||
|
||||
namespace rapidjson {
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// ParseErrorCode
|
||||
|
||||
//! Error code of parsing.
|
||||
/*! \see GenericReader::Parse, GenericReader::GetParseErrorCode
|
||||
*/
|
||||
enum ParseErrorCode {
|
||||
kParseErrorNone = 0, //!< No error.
|
||||
|
||||
kParseErrorDocumentEmpty, //!< The document is empty.
|
||||
kParseErrorDocumentRootNotObjectOrArray, //!< The document root must be either object or array.
|
||||
kParseErrorDocumentRootNotSingular, //!< The document root must not follow by other values.
|
||||
|
||||
kParseErrorValueInvalid, //!< Invalid value.
|
||||
|
||||
kParseErrorObjectMissName, //!< Missing a name for object member.
|
||||
kParseErrorObjectMissColon, //!< Missing a colon after a name of object member.
|
||||
kParseErrorObjectMissCommaOrCurlyBracket, //!< Missing a comma or '}' after an object member.
|
||||
|
||||
kParseErrorArrayMissCommaOrSquareBracket, //!< Missing a comma or ']' after an array element.
|
||||
|
||||
kParseErrorStringUnicodeEscapeInvalidHex, //!< Incorrect hex digit after \\u escape in string.
|
||||
kParseErrorStringUnicodeSurrogateInvalid, //!< The surrogate pair in string is invalid.
|
||||
kParseErrorStringEscapeInvalid, //!< Invalid escape character in string.
|
||||
kParseErrorStringMissQuotationMark, //!< Missing a closing quotation mark in string.
|
||||
kParseErrorStringInvalidEncoding, //!< Invalid encoding in string.
|
||||
|
||||
kParseErrorNumberTooBig, //!< Number too big to be stored in double.
|
||||
kParseErrorNumberMissFraction, //!< Miss fraction part in number.
|
||||
kParseErrorNumberMissExponent, //!< Miss exponent in number.
|
||||
|
||||
kParseErrorTermination, //!< Parsing was terminated.
|
||||
kParseErrorUnspecificSyntaxError, //!< Unspecific syntax error.
|
||||
kParseErrorStackSizeLimitExceeded //!< Parsing stack size limit is exceeded.
|
||||
};
|
||||
|
||||
//! Result of parsing (wraps ParseErrorCode)
|
||||
/*!
|
||||
\code
|
||||
Document doc;
|
||||
ParseResult ok = doc.Parse("[42]");
|
||||
if (!ok) {
|
||||
fprintf(stderr, "JSON parse error: %s (%u)",
|
||||
GetParseError_En(ok.Code()), ok.Offset());
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
\endcode
|
||||
\see GenericReader::Parse, GenericDocument::Parse
|
||||
*/
|
||||
struct ParseResult {
|
||||
|
||||
//! Default constructor, no error.
|
||||
ParseResult() : code_(kParseErrorNone), offset_(0) {}
|
||||
//! Constructor to set an error.
|
||||
ParseResult(ParseErrorCode code, size_t offset) : code_(code), offset_(offset) {}
|
||||
|
||||
//! Get the error code.
|
||||
ParseErrorCode Code() const { return code_; }
|
||||
//! Get the error offset, if \ref IsError(), 0 otherwise.
|
||||
size_t Offset() const { return offset_; }
|
||||
|
||||
//! Conversion to \c bool, returns \c true, iff !\ref IsError().
|
||||
operator bool() const { return !IsError(); }
|
||||
//! Whether the result is an error.
|
||||
bool IsError() const { return code_ != kParseErrorNone; }
|
||||
|
||||
bool operator==(const ParseResult& that) const { return code_ == that.code_; }
|
||||
bool operator==(ParseErrorCode code) const { return code_ == code; }
|
||||
friend bool operator==(ParseErrorCode code, const ParseResult & err) { return code == err.code_; }
|
||||
|
||||
//! Reset error code.
|
||||
void Clear() { Set(kParseErrorNone); }
|
||||
//! Update error code and offset.
|
||||
void Set(ParseErrorCode code, size_t offset = 0) { code_ = code; offset_ = offset; }
|
||||
|
||||
private:
|
||||
ParseErrorCode code_;
|
||||
size_t offset_;
|
||||
};
|
||||
|
||||
//! Function pointer type of GetParseError().
|
||||
/*! This is the prototype for GetParseError_X(), where X is a locale.
|
||||
User can dynamically change locale in runtime, e.g.:
|
||||
|
||||
\code
|
||||
GetParseErrorFunc GetParseError = GetParseError_En; // or whatever
|
||||
const RAPIDJSON_ERROR_CHARTYPE* s = GetParseError(document.GetParseErrorCode());
|
||||
\endcode
|
||||
*/
|
||||
|
||||
typedef const RAPIDJSON_ERROR_CHARTYPE* (*GetParseErrorFunc)(ParseErrorCode);
|
||||
|
||||
} // namespace rapidjson
|
||||
|
||||
#endif // RAPIDJSON_ERROR_ERROR_H__
|
||||
@@ -0,0 +1,74 @@
|
||||
#ifndef RAPIDJSON_FILEREADSTREAM_H_
|
||||
#define RAPIDJSON_FILEREADSTREAM_H_
|
||||
|
||||
#include "rapidjson.h"
|
||||
#include <cstdio>
|
||||
|
||||
namespace rapidjson {
|
||||
|
||||
//! File byte stream for input using fread().
|
||||
/*!
|
||||
\note implements Stream concept
|
||||
*/
|
||||
class FileReadStream {
|
||||
public:
|
||||
typedef char Ch; //!< Character type (byte).
|
||||
|
||||
//! Constructor.
|
||||
/*!
|
||||
\param fp File pointer opened for read.
|
||||
\param buffer user-supplied buffer.
|
||||
\param bufferSize size of buffer in bytes. Must >=4 bytes.
|
||||
*/
|
||||
FileReadStream(FILE* fp, char* buffer, size_t bufferSize) : fp_(fp), buffer_(buffer), bufferSize_(bufferSize), bufferLast_(0), current_(buffer_), readCount_(0), count_(0), eof_(false) {
|
||||
RAPIDJSON_ASSERT(fp_ != 0);
|
||||
RAPIDJSON_ASSERT(bufferSize >= 4);
|
||||
Read();
|
||||
}
|
||||
|
||||
Ch Peek() const { return *current_; }
|
||||
Ch Take() { Ch c = *current_; Read(); return c; }
|
||||
size_t Tell() const { return count_ + static_cast<size_t>(current_ - buffer_); }
|
||||
|
||||
// Not implemented
|
||||
void Put(Ch) { RAPIDJSON_ASSERT(false); }
|
||||
void Flush() { RAPIDJSON_ASSERT(false); }
|
||||
Ch* PutBegin() { RAPIDJSON_ASSERT(false); return 0; }
|
||||
size_t PutEnd(Ch*) { RAPIDJSON_ASSERT(false); return 0; }
|
||||
|
||||
// For encoding detection only.
|
||||
const Ch* Peek4() const {
|
||||
return (current_ + 4 <= bufferLast_) ? current_ : 0;
|
||||
}
|
||||
|
||||
private:
|
||||
void Read() {
|
||||
if (current_ < bufferLast_)
|
||||
++current_;
|
||||
else if (!eof_) {
|
||||
count_ += readCount_;
|
||||
readCount_ = fread(buffer_, 1, bufferSize_, fp_);
|
||||
bufferLast_ = buffer_ + readCount_ - 1;
|
||||
current_ = buffer_;
|
||||
|
||||
if (readCount_ < bufferSize_) {
|
||||
buffer_[readCount_] = '\0';
|
||||
++bufferLast_;
|
||||
eof_ = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
FILE* fp_;
|
||||
Ch *buffer_;
|
||||
size_t bufferSize_;
|
||||
Ch *bufferLast_;
|
||||
Ch *current_;
|
||||
size_t readCount_;
|
||||
size_t count_; //!< Number of characters read
|
||||
bool eof_;
|
||||
};
|
||||
|
||||
} // namespace rapidjson
|
||||
|
||||
#endif // RAPIDJSON_FILESTREAM_H_
|
||||
@@ -0,0 +1,53 @@
|
||||
#ifndef RAPIDJSON_FILESTREAM_H_
|
||||
#define RAPIDJSON_FILESTREAM_H_
|
||||
|
||||
#include "rapidjson.h"
|
||||
#include <cstdio>
|
||||
|
||||
namespace rapidjson {
|
||||
|
||||
//! (Depreciated) Wrapper of C file stream for input or output.
|
||||
/*!
|
||||
This simple wrapper does not check the validity of the stream.
|
||||
\note implements Stream concept
|
||||
\note deprecated: This was only for basic testing in version 0.1, it is found that the performance is very low by using fgetc(). Use FileReadStream instead.
|
||||
*/
|
||||
class FileStream {
|
||||
public:
|
||||
typedef char Ch; //!< Character type. Only support char.
|
||||
|
||||
FileStream(FILE* fp) : fp_(fp), current_('\0'), count_(0) { Read(); }
|
||||
char Peek() const { return current_; }
|
||||
char Take() { char c = current_; Read(); return c; }
|
||||
size_t Tell() const { return count_; }
|
||||
void Put(char c) { fputc(c, fp_); }
|
||||
void Flush() { fflush(fp_); }
|
||||
|
||||
// Not implemented
|
||||
char* PutBegin() { return 0; }
|
||||
size_t PutEnd(char*) { return 0; }
|
||||
|
||||
private:
|
||||
// Prohibit copy constructor & assignment operator.
|
||||
FileStream(const FileStream&);
|
||||
FileStream& operator=(const FileStream&);
|
||||
|
||||
void Read() {
|
||||
RAPIDJSON_ASSERT(fp_ != 0);
|
||||
int c = fgetc(fp_);
|
||||
if (c != EOF) {
|
||||
current_ = (char)c;
|
||||
count_++;
|
||||
}
|
||||
else if (current_ != '\0')
|
||||
current_ = '\0';
|
||||
}
|
||||
|
||||
FILE* fp_;
|
||||
char current_;
|
||||
size_t count_;
|
||||
};
|
||||
|
||||
} // namespace rapidjson
|
||||
|
||||
#endif // RAPIDJSON_FILESTREAM_H_
|
||||
@@ -0,0 +1,77 @@
|
||||
#ifndef RAPIDJSON_FILEWRITESTREAM_H_
|
||||
#define RAPIDJSON_FILEWRITESTREAM_H_
|
||||
|
||||
#include "rapidjson.h"
|
||||
#include <cstdio>
|
||||
|
||||
namespace rapidjson {
|
||||
|
||||
//! Wrapper of C file stream for input using fread().
|
||||
/*!
|
||||
\note implements Stream concept
|
||||
*/
|
||||
class FileWriteStream {
|
||||
public:
|
||||
typedef char Ch; //!< Character type. Only support char.
|
||||
|
||||
FileWriteStream(FILE* fp, char* buffer, size_t bufferSize) : fp_(fp), buffer_(buffer), bufferEnd_(buffer + bufferSize), current_(buffer_) {
|
||||
RAPIDJSON_ASSERT(fp_ != 0);
|
||||
}
|
||||
|
||||
void Put(char c) {
|
||||
if (current_ >= bufferEnd_)
|
||||
Flush();
|
||||
|
||||
*current_++ = c;
|
||||
}
|
||||
|
||||
void PutN(char c, size_t n) {
|
||||
size_t avail = static_cast<size_t>(bufferEnd_ - current_);
|
||||
while (n > avail) {
|
||||
memset(current_, c, avail);
|
||||
current_ += avail;
|
||||
Flush();
|
||||
n -= avail;
|
||||
avail = static_cast<size_t>(bufferEnd_ - current_);
|
||||
}
|
||||
|
||||
if (n > 0) {
|
||||
memset(current_, c, n);
|
||||
current_ += n;
|
||||
}
|
||||
}
|
||||
|
||||
void Flush() {
|
||||
if (current_ != buffer_) {
|
||||
fwrite(buffer_, 1, static_cast<size_t>(current_ - buffer_), fp_);
|
||||
current_ = buffer_;
|
||||
}
|
||||
}
|
||||
|
||||
// Not implemented
|
||||
char Peek() const { RAPIDJSON_ASSERT(false); return 0; }
|
||||
char Take() { RAPIDJSON_ASSERT(false); return 0; }
|
||||
size_t Tell() const { RAPIDJSON_ASSERT(false); return 0; }
|
||||
char* PutBegin() { RAPIDJSON_ASSERT(false); return 0; }
|
||||
size_t PutEnd(char*) { RAPIDJSON_ASSERT(false); return 0; }
|
||||
|
||||
private:
|
||||
// Prohibit copy constructor & assignment operator.
|
||||
FileWriteStream(const FileWriteStream&);
|
||||
FileWriteStream& operator=(const FileWriteStream&);
|
||||
|
||||
FILE* fp_;
|
||||
char *buffer_;
|
||||
char *bufferEnd_;
|
||||
char *current_;
|
||||
};
|
||||
|
||||
//! Implement specialized version of PutN() with memset() for better performance.
|
||||
template<>
|
||||
inline void PutN(FileWriteStream& stream, char c, size_t n) {
|
||||
stream.PutN(c, n);
|
||||
}
|
||||
|
||||
} // namespace rapidjson
|
||||
|
||||
#endif // RAPIDJSON_FILESTREAM_H_
|
||||
@@ -0,0 +1,77 @@
|
||||
#ifndef RAPIDJSON_INTERNAL_META_H_
|
||||
#define RAPIDJSON_INTERNAL_META_H_
|
||||
|
||||
//@cond RAPIDJSON_INTERNAL
|
||||
namespace rapidjson {
|
||||
namespace internal {
|
||||
|
||||
template <int N> struct IntegralC { enum { Value = N }; };
|
||||
template <bool Cond> struct BoolType : IntegralC<Cond> {};
|
||||
struct TrueType : BoolType<true> {};
|
||||
struct FalseType : BoolType<false> {};
|
||||
|
||||
template <typename T> struct AddConst { typedef const T Type; };
|
||||
template <typename T> struct RemoveConst { typedef T Type; };
|
||||
template <typename T> struct RemoveConst<const T> { typedef T Type; };
|
||||
|
||||
template <bool Condition, typename T1, typename T2> struct SelectIfCond;
|
||||
template <typename T1, typename T2> struct SelectIfCond<true,T1,T2> { typedef T1 Type; };
|
||||
template <typename T1, typename T2> struct SelectIfCond<false,T1,T2> { typedef T2 Type; };
|
||||
|
||||
template <typename Condition, typename T1, typename T2>
|
||||
struct SelectIf : SelectIfCond<Condition::Value,T1,T2> {};
|
||||
|
||||
template <bool Constify, typename T>
|
||||
struct MaybeAddConst : SelectIfCond<Constify, const T, T> {};
|
||||
|
||||
template <typename T, typename U> struct IsSame : FalseType {};
|
||||
template <typename T> struct IsSame<T,T> : TrueType {};
|
||||
|
||||
template <typename T> struct IsConst : FalseType {};
|
||||
template <typename T> struct IsConst<const T> : TrueType {};
|
||||
|
||||
template <typename T> struct IsPointer : FalseType {};
|
||||
template <typename T> struct IsPointer<T*> : TrueType {};
|
||||
|
||||
template <typename CT, typename T>
|
||||
struct IsMoreConst {
|
||||
enum { Value =
|
||||
( IsSame< typename RemoveConst<CT>::Type, typename RemoveConst<T>::Type>::Value
|
||||
&& ( IsConst<CT>::Value >= IsConst<T>::Value ) )
|
||||
};
|
||||
};
|
||||
|
||||
template <bool Condition, typename T = void> struct EnableIfCond;
|
||||
template <typename T> struct EnableIfCond<true, T> { typedef T Type; };
|
||||
template <typename T> struct EnableIfCond<false, T> { /* empty */ };
|
||||
|
||||
template <bool Condition, typename T = void>
|
||||
struct DisableIfCond : EnableIfCond<!Condition, T> {};
|
||||
|
||||
template <typename Condition, typename T = void>
|
||||
struct EnableIf : EnableIfCond<Condition::Value, T> {};
|
||||
|
||||
template <typename Condition, typename T = void>
|
||||
struct DisableIf : DisableIfCond<Condition::Value, T> {};
|
||||
|
||||
// SFINAE helpers
|
||||
struct SfinaeResultTag {};
|
||||
template <typename T> struct RemoveSfinaeFptr {};
|
||||
template <typename T> struct RemoveSfinaeFptr<SfinaeResultTag&(*)(T)> { typedef T Type; };
|
||||
|
||||
#define RAPIDJSON_REMOVEFPTR_(type) \
|
||||
typename ::rapidjson::internal::RemoveSfinaeFptr \
|
||||
< ::rapidjson::internal::SfinaeResultTag&(*) type>::Type
|
||||
|
||||
#define RAPIDJSON_ENABLEIF(cond) \
|
||||
typename ::rapidjson::internal::EnableIf \
|
||||
<RAPIDJSON_REMOVEFPTR_(cond)>::Type * = NULL
|
||||
|
||||
#define RAPIDJSON_DISABLEIF_RETURN(cond,returntype) \
|
||||
typename ::rapidjson::internal::DisableIf<cond,returntype>::Type
|
||||
|
||||
} // namespace internal
|
||||
} // namespace rapidjson
|
||||
//@endcond
|
||||
|
||||
#endif // RAPIDJSON_INTERNAL_META_H_
|
||||
@@ -0,0 +1,54 @@
|
||||
#ifndef RAPIDJSON_POW10_
|
||||
#define RAPIDJSON_POW10_
|
||||
|
||||
namespace rapidjson {
|
||||
namespace internal {
|
||||
|
||||
//! Computes integer powers of 10 in double (10.0^n).
|
||||
/*! This function uses lookup table for fast and accurate results.
|
||||
\param n positive/negative exponent. Must <= 308.
|
||||
\return 10.0^n
|
||||
*/
|
||||
inline double Pow10(int n) {
|
||||
static const double e[] = { // 1e-308...1e308: 617 * 8 bytes = 4936 bytes
|
||||
1e-308,1e-307,1e-306,1e-305,1e-304,1e-303,1e-302,1e-301,1e-300,
|
||||
1e-299,1e-298,1e-297,1e-296,1e-295,1e-294,1e-293,1e-292,1e-291,1e-290,1e-289,1e-288,1e-287,1e-286,1e-285,1e-284,1e-283,1e-282,1e-281,1e-280,
|
||||
1e-279,1e-278,1e-277,1e-276,1e-275,1e-274,1e-273,1e-272,1e-271,1e-270,1e-269,1e-268,1e-267,1e-266,1e-265,1e-264,1e-263,1e-262,1e-261,1e-260,
|
||||
1e-259,1e-258,1e-257,1e-256,1e-255,1e-254,1e-253,1e-252,1e-251,1e-250,1e-249,1e-248,1e-247,1e-246,1e-245,1e-244,1e-243,1e-242,1e-241,1e-240,
|
||||
1e-239,1e-238,1e-237,1e-236,1e-235,1e-234,1e-233,1e-232,1e-231,1e-230,1e-229,1e-228,1e-227,1e-226,1e-225,1e-224,1e-223,1e-222,1e-221,1e-220,
|
||||
1e-219,1e-218,1e-217,1e-216,1e-215,1e-214,1e-213,1e-212,1e-211,1e-210,1e-209,1e-208,1e-207,1e-206,1e-205,1e-204,1e-203,1e-202,1e-201,1e-200,
|
||||
1e-199,1e-198,1e-197,1e-196,1e-195,1e-194,1e-193,1e-192,1e-191,1e-190,1e-189,1e-188,1e-187,1e-186,1e-185,1e-184,1e-183,1e-182,1e-181,1e-180,
|
||||
1e-179,1e-178,1e-177,1e-176,1e-175,1e-174,1e-173,1e-172,1e-171,1e-170,1e-169,1e-168,1e-167,1e-166,1e-165,1e-164,1e-163,1e-162,1e-161,1e-160,
|
||||
1e-159,1e-158,1e-157,1e-156,1e-155,1e-154,1e-153,1e-152,1e-151,1e-150,1e-149,1e-148,1e-147,1e-146,1e-145,1e-144,1e-143,1e-142,1e-141,1e-140,
|
||||
1e-139,1e-138,1e-137,1e-136,1e-135,1e-134,1e-133,1e-132,1e-131,1e-130,1e-129,1e-128,1e-127,1e-126,1e-125,1e-124,1e-123,1e-122,1e-121,1e-120,
|
||||
1e-119,1e-118,1e-117,1e-116,1e-115,1e-114,1e-113,1e-112,1e-111,1e-110,1e-109,1e-108,1e-107,1e-106,1e-105,1e-104,1e-103,1e-102,1e-101,1e-100,
|
||||
1e-99, 1e-98, 1e-97, 1e-96, 1e-95, 1e-94, 1e-93, 1e-92, 1e-91, 1e-90, 1e-89, 1e-88, 1e-87, 1e-86, 1e-85, 1e-84, 1e-83, 1e-82, 1e-81, 1e-80,
|
||||
1e-79, 1e-78, 1e-77, 1e-76, 1e-75, 1e-74, 1e-73, 1e-72, 1e-71, 1e-70, 1e-69, 1e-68, 1e-67, 1e-66, 1e-65, 1e-64, 1e-63, 1e-62, 1e-61, 1e-60,
|
||||
1e-59, 1e-58, 1e-57, 1e-56, 1e-55, 1e-54, 1e-53, 1e-52, 1e-51, 1e-50, 1e-49, 1e-48, 1e-47, 1e-46, 1e-45, 1e-44, 1e-43, 1e-42, 1e-41, 1e-40,
|
||||
1e-39, 1e-38, 1e-37, 1e-36, 1e-35, 1e-34, 1e-33, 1e-32, 1e-31, 1e-30, 1e-29, 1e-28, 1e-27, 1e-26, 1e-25, 1e-24, 1e-23, 1e-22, 1e-21, 1e-20,
|
||||
1e-19, 1e-18, 1e-17, 1e-16, 1e-15, 1e-14, 1e-13, 1e-12, 1e-11, 1e-10, 1e-9, 1e-8, 1e-7, 1e-6, 1e-5, 1e-4, 1e-3, 1e-2, 1e-1, 1e+0,
|
||||
1e+1, 1e+2, 1e+3, 1e+4, 1e+5, 1e+6, 1e+7, 1e+8, 1e+9, 1e+10, 1e+11, 1e+12, 1e+13, 1e+14, 1e+15, 1e+16, 1e+17, 1e+18, 1e+19, 1e+20,
|
||||
1e+21, 1e+22, 1e+23, 1e+24, 1e+25, 1e+26, 1e+27, 1e+28, 1e+29, 1e+30, 1e+31, 1e+32, 1e+33, 1e+34, 1e+35, 1e+36, 1e+37, 1e+38, 1e+39, 1e+40,
|
||||
1e+41, 1e+42, 1e+43, 1e+44, 1e+45, 1e+46, 1e+47, 1e+48, 1e+49, 1e+50, 1e+51, 1e+52, 1e+53, 1e+54, 1e+55, 1e+56, 1e+57, 1e+58, 1e+59, 1e+60,
|
||||
1e+61, 1e+62, 1e+63, 1e+64, 1e+65, 1e+66, 1e+67, 1e+68, 1e+69, 1e+70, 1e+71, 1e+72, 1e+73, 1e+74, 1e+75, 1e+76, 1e+77, 1e+78, 1e+79, 1e+80,
|
||||
1e+81, 1e+82, 1e+83, 1e+84, 1e+85, 1e+86, 1e+87, 1e+88, 1e+89, 1e+90, 1e+91, 1e+92, 1e+93, 1e+94, 1e+95, 1e+96, 1e+97, 1e+98, 1e+99, 1e+100,
|
||||
1e+101,1e+102,1e+103,1e+104,1e+105,1e+106,1e+107,1e+108,1e+109,1e+110,1e+111,1e+112,1e+113,1e+114,1e+115,1e+116,1e+117,1e+118,1e+119,1e+120,
|
||||
1e+121,1e+122,1e+123,1e+124,1e+125,1e+126,1e+127,1e+128,1e+129,1e+130,1e+131,1e+132,1e+133,1e+134,1e+135,1e+136,1e+137,1e+138,1e+139,1e+140,
|
||||
1e+141,1e+142,1e+143,1e+144,1e+145,1e+146,1e+147,1e+148,1e+149,1e+150,1e+151,1e+152,1e+153,1e+154,1e+155,1e+156,1e+157,1e+158,1e+159,1e+160,
|
||||
1e+161,1e+162,1e+163,1e+164,1e+165,1e+166,1e+167,1e+168,1e+169,1e+170,1e+171,1e+172,1e+173,1e+174,1e+175,1e+176,1e+177,1e+178,1e+179,1e+180,
|
||||
1e+181,1e+182,1e+183,1e+184,1e+185,1e+186,1e+187,1e+188,1e+189,1e+190,1e+191,1e+192,1e+193,1e+194,1e+195,1e+196,1e+197,1e+198,1e+199,1e+200,
|
||||
1e+201,1e+202,1e+203,1e+204,1e+205,1e+206,1e+207,1e+208,1e+209,1e+210,1e+211,1e+212,1e+213,1e+214,1e+215,1e+216,1e+217,1e+218,1e+219,1e+220,
|
||||
1e+221,1e+222,1e+223,1e+224,1e+225,1e+226,1e+227,1e+228,1e+229,1e+230,1e+231,1e+232,1e+233,1e+234,1e+235,1e+236,1e+237,1e+238,1e+239,1e+240,
|
||||
1e+241,1e+242,1e+243,1e+244,1e+245,1e+246,1e+247,1e+248,1e+249,1e+250,1e+251,1e+252,1e+253,1e+254,1e+255,1e+256,1e+257,1e+258,1e+259,1e+260,
|
||||
1e+261,1e+262,1e+263,1e+264,1e+265,1e+266,1e+267,1e+268,1e+269,1e+270,1e+271,1e+272,1e+273,1e+274,1e+275,1e+276,1e+277,1e+278,1e+279,1e+280,
|
||||
1e+281,1e+282,1e+283,1e+284,1e+285,1e+286,1e+287,1e+288,1e+289,1e+290,1e+291,1e+292,1e+293,1e+294,1e+295,1e+296,1e+297,1e+298,1e+299,1e+300,
|
||||
1e+301,1e+302,1e+303,1e+304,1e+305,1e+306,1e+307,1e+308
|
||||
};
|
||||
RAPIDJSON_ASSERT(n <= 308);
|
||||
return n < -308 ? 0.0 : e[n + 308];
|
||||
}
|
||||
|
||||
} // namespace internal
|
||||
} // namespace rapidjson
|
||||
|
||||
#endif // RAPIDJSON_POW10_
|
||||
@@ -0,0 +1,87 @@
|
||||
#ifndef RAPIDJSON_INTERNAL_STACK_H_
|
||||
#define RAPIDJSON_INTERNAL_STACK_H_
|
||||
|
||||
namespace rapidjson {
|
||||
namespace internal {
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Stack
|
||||
|
||||
//! A type-unsafe stack for storing different types of data.
|
||||
/*! \tparam Allocator Allocator for allocating stack memory.
|
||||
*/
|
||||
template <typename Allocator>
|
||||
class Stack {
|
||||
public:
|
||||
Stack(Allocator* allocator, size_t stack_capacity) : allocator_(allocator), own_allocator_(0), stack_(0), stack_top_(0), stack_end_(0), stack_capacity_(stack_capacity) {
|
||||
RAPIDJSON_ASSERT(stack_capacity_ > 0);
|
||||
if (!allocator_)
|
||||
own_allocator_ = allocator_ = new Allocator();
|
||||
stack_top_ = stack_ = (char*)allocator_->Malloc(stack_capacity_);
|
||||
stack_end_ = stack_ + stack_capacity_;
|
||||
}
|
||||
|
||||
~Stack() {
|
||||
Allocator::Free(stack_);
|
||||
delete own_allocator_; // Only delete if it is owned by the stack
|
||||
}
|
||||
|
||||
void Clear() { /*stack_top_ = 0;*/ stack_top_ = stack_; }
|
||||
|
||||
template<typename T>
|
||||
T* Push(size_t count = 1) {
|
||||
// Expand the stack if needed
|
||||
if (stack_top_ + sizeof(T) * count >= stack_end_) {
|
||||
size_t new_capacity = stack_capacity_ * 2;
|
||||
size_t size = GetSize();
|
||||
size_t new_size = GetSize() + sizeof(T) * count;
|
||||
if (new_capacity < new_size)
|
||||
new_capacity = new_size;
|
||||
stack_ = (char*)allocator_->Realloc(stack_, stack_capacity_, new_capacity);
|
||||
stack_capacity_ = new_capacity;
|
||||
stack_top_ = stack_ + size;
|
||||
stack_end_ = stack_ + stack_capacity_;
|
||||
}
|
||||
T* ret = reinterpret_cast<T*>(stack_top_);
|
||||
stack_top_ += sizeof(T) * count;
|
||||
return ret;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
T* Pop(size_t count) {
|
||||
RAPIDJSON_ASSERT(GetSize() >= count * sizeof(T));
|
||||
stack_top_ -= count * sizeof(T);
|
||||
return reinterpret_cast<T*>(stack_top_);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
T* Top() {
|
||||
RAPIDJSON_ASSERT(GetSize() >= sizeof(T));
|
||||
return reinterpret_cast<T*>(stack_top_ - sizeof(T));
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
T* Bottom() { return (T*)stack_; }
|
||||
|
||||
Allocator& GetAllocator() { return *allocator_; }
|
||||
bool Empty() const { return stack_top_ == stack_; }
|
||||
size_t GetSize() const { return static_cast<size_t>(stack_top_ - stack_); }
|
||||
size_t GetCapacity() const { return stack_capacity_; }
|
||||
|
||||
private:
|
||||
// Prohibit copy constructor & assignment operator.
|
||||
Stack(const Stack&);
|
||||
Stack& operator=(const Stack&);
|
||||
|
||||
Allocator* allocator_;
|
||||
Allocator* own_allocator_;
|
||||
char *stack_;
|
||||
char *stack_top_;
|
||||
char *stack_end_;
|
||||
size_t stack_capacity_;
|
||||
};
|
||||
|
||||
} // namespace internal
|
||||
} // namespace rapidjson
|
||||
|
||||
#endif // RAPIDJSON_STACK_H_
|
||||
@@ -0,0 +1,23 @@
|
||||
#ifndef RAPIDJSON_INTERNAL_STRFUNC_H_
|
||||
#define RAPIDJSON_INTERNAL_STRFUNC_H_
|
||||
|
||||
namespace rapidjson {
|
||||
namespace internal {
|
||||
|
||||
//! Custom strlen() which works on different character types.
|
||||
/*! \tparam Ch Character type (e.g. char, wchar_t, short)
|
||||
\param s Null-terminated input string.
|
||||
\return Number of characters in the string.
|
||||
\note This has the same semantics as strlen(), the return value is not number of Unicode codepoints.
|
||||
*/
|
||||
template <typename Ch>
|
||||
inline SizeType StrLen(const Ch* s) {
|
||||
const Ch* p = s;
|
||||
while (*p) ++p;
|
||||
return SizeType(p - s);
|
||||
}
|
||||
|
||||
} // namespace internal
|
||||
} // namespace rapidjson
|
||||
|
||||
#endif // RAPIDJSON_INTERNAL_STRFUNC_H_
|
||||
@@ -0,0 +1,306 @@
|
||||
// ISO C9x compliant inttypes.h for Microsoft Visual Studio
|
||||
// Based on ISO/IEC 9899:TC2 Committee draft (May 6, 2005) WG14/N1124
|
||||
//
|
||||
// Copyright (c) 2006-2013 Alexander Chemeris
|
||||
//
|
||||
// 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. Neither the name of the product 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 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.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef _MSC_VER // [
|
||||
#error "Use this header only with Microsoft Visual C++ compilers!"
|
||||
#endif // _MSC_VER ]
|
||||
|
||||
#ifndef _MSC_INTTYPES_H_ // [
|
||||
#define _MSC_INTTYPES_H_
|
||||
|
||||
#if _MSC_VER > 1000
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "stdint.h"
|
||||
|
||||
// 7.8 Format conversion of integer types
|
||||
|
||||
typedef struct {
|
||||
intmax_t quot;
|
||||
intmax_t rem;
|
||||
} imaxdiv_t;
|
||||
|
||||
// 7.8.1 Macros for format specifiers
|
||||
|
||||
#if !defined(__cplusplus) || defined(__STDC_FORMAT_MACROS) // [ See footnote 185 at page 198
|
||||
|
||||
// The fprintf macros for signed integers are:
|
||||
#define PRId8 "d"
|
||||
#define PRIi8 "i"
|
||||
#define PRIdLEAST8 "d"
|
||||
#define PRIiLEAST8 "i"
|
||||
#define PRIdFAST8 "d"
|
||||
#define PRIiFAST8 "i"
|
||||
|
||||
#define PRId16 "hd"
|
||||
#define PRIi16 "hi"
|
||||
#define PRIdLEAST16 "hd"
|
||||
#define PRIiLEAST16 "hi"
|
||||
#define PRIdFAST16 "hd"
|
||||
#define PRIiFAST16 "hi"
|
||||
|
||||
#define PRId32 "I32d"
|
||||
#define PRIi32 "I32i"
|
||||
#define PRIdLEAST32 "I32d"
|
||||
#define PRIiLEAST32 "I32i"
|
||||
#define PRIdFAST32 "I32d"
|
||||
#define PRIiFAST32 "I32i"
|
||||
|
||||
#define PRId64 "I64d"
|
||||
#define PRIi64 "I64i"
|
||||
#define PRIdLEAST64 "I64d"
|
||||
#define PRIiLEAST64 "I64i"
|
||||
#define PRIdFAST64 "I64d"
|
||||
#define PRIiFAST64 "I64i"
|
||||
|
||||
#define PRIdMAX "I64d"
|
||||
#define PRIiMAX "I64i"
|
||||
|
||||
#define PRIdPTR "Id"
|
||||
#define PRIiPTR "Ii"
|
||||
|
||||
// The fprintf macros for unsigned integers are:
|
||||
#define PRIo8 "o"
|
||||
#define PRIu8 "u"
|
||||
#define PRIx8 "x"
|
||||
#define PRIX8 "X"
|
||||
#define PRIoLEAST8 "o"
|
||||
#define PRIuLEAST8 "u"
|
||||
#define PRIxLEAST8 "x"
|
||||
#define PRIXLEAST8 "X"
|
||||
#define PRIoFAST8 "o"
|
||||
#define PRIuFAST8 "u"
|
||||
#define PRIxFAST8 "x"
|
||||
#define PRIXFAST8 "X"
|
||||
|
||||
#define PRIo16 "ho"
|
||||
#define PRIu16 "hu"
|
||||
#define PRIx16 "hx"
|
||||
#define PRIX16 "hX"
|
||||
#define PRIoLEAST16 "ho"
|
||||
#define PRIuLEAST16 "hu"
|
||||
#define PRIxLEAST16 "hx"
|
||||
#define PRIXLEAST16 "hX"
|
||||
#define PRIoFAST16 "ho"
|
||||
#define PRIuFAST16 "hu"
|
||||
#define PRIxFAST16 "hx"
|
||||
#define PRIXFAST16 "hX"
|
||||
|
||||
#define PRIo32 "I32o"
|
||||
#define PRIu32 "I32u"
|
||||
#define PRIx32 "I32x"
|
||||
#define PRIX32 "I32X"
|
||||
#define PRIoLEAST32 "I32o"
|
||||
#define PRIuLEAST32 "I32u"
|
||||
#define PRIxLEAST32 "I32x"
|
||||
#define PRIXLEAST32 "I32X"
|
||||
#define PRIoFAST32 "I32o"
|
||||
#define PRIuFAST32 "I32u"
|
||||
#define PRIxFAST32 "I32x"
|
||||
#define PRIXFAST32 "I32X"
|
||||
|
||||
#define PRIo64 "I64o"
|
||||
#define PRIu64 "I64u"
|
||||
#define PRIx64 "I64x"
|
||||
#define PRIX64 "I64X"
|
||||
#define PRIoLEAST64 "I64o"
|
||||
#define PRIuLEAST64 "I64u"
|
||||
#define PRIxLEAST64 "I64x"
|
||||
#define PRIXLEAST64 "I64X"
|
||||
#define PRIoFAST64 "I64o"
|
||||
#define PRIuFAST64 "I64u"
|
||||
#define PRIxFAST64 "I64x"
|
||||
#define PRIXFAST64 "I64X"
|
||||
|
||||
#define PRIoMAX "I64o"
|
||||
#define PRIuMAX "I64u"
|
||||
#define PRIxMAX "I64x"
|
||||
#define PRIXMAX "I64X"
|
||||
|
||||
#define PRIoPTR "Io"
|
||||
#define PRIuPTR "Iu"
|
||||
#define PRIxPTR "Ix"
|
||||
#define PRIXPTR "IX"
|
||||
|
||||
// The fscanf macros for signed integers are:
|
||||
#define SCNd8 "d"
|
||||
#define SCNi8 "i"
|
||||
#define SCNdLEAST8 "d"
|
||||
#define SCNiLEAST8 "i"
|
||||
#define SCNdFAST8 "d"
|
||||
#define SCNiFAST8 "i"
|
||||
|
||||
#define SCNd16 "hd"
|
||||
#define SCNi16 "hi"
|
||||
#define SCNdLEAST16 "hd"
|
||||
#define SCNiLEAST16 "hi"
|
||||
#define SCNdFAST16 "hd"
|
||||
#define SCNiFAST16 "hi"
|
||||
|
||||
#define SCNd32 "ld"
|
||||
#define SCNi32 "li"
|
||||
#define SCNdLEAST32 "ld"
|
||||
#define SCNiLEAST32 "li"
|
||||
#define SCNdFAST32 "ld"
|
||||
#define SCNiFAST32 "li"
|
||||
|
||||
#define SCNd64 "I64d"
|
||||
#define SCNi64 "I64i"
|
||||
#define SCNdLEAST64 "I64d"
|
||||
#define SCNiLEAST64 "I64i"
|
||||
#define SCNdFAST64 "I64d"
|
||||
#define SCNiFAST64 "I64i"
|
||||
|
||||
#define SCNdMAX "I64d"
|
||||
#define SCNiMAX "I64i"
|
||||
|
||||
#ifdef _WIN64 // [
|
||||
# define SCNdPTR "I64d"
|
||||
# define SCNiPTR "I64i"
|
||||
#else // _WIN64 ][
|
||||
# define SCNdPTR "ld"
|
||||
# define SCNiPTR "li"
|
||||
#endif // _WIN64 ]
|
||||
|
||||
// The fscanf macros for unsigned integers are:
|
||||
#define SCNo8 "o"
|
||||
#define SCNu8 "u"
|
||||
#define SCNx8 "x"
|
||||
#define SCNX8 "X"
|
||||
#define SCNoLEAST8 "o"
|
||||
#define SCNuLEAST8 "u"
|
||||
#define SCNxLEAST8 "x"
|
||||
#define SCNXLEAST8 "X"
|
||||
#define SCNoFAST8 "o"
|
||||
#define SCNuFAST8 "u"
|
||||
#define SCNxFAST8 "x"
|
||||
#define SCNXFAST8 "X"
|
||||
|
||||
#define SCNo16 "ho"
|
||||
#define SCNu16 "hu"
|
||||
#define SCNx16 "hx"
|
||||
#define SCNX16 "hX"
|
||||
#define SCNoLEAST16 "ho"
|
||||
#define SCNuLEAST16 "hu"
|
||||
#define SCNxLEAST16 "hx"
|
||||
#define SCNXLEAST16 "hX"
|
||||
#define SCNoFAST16 "ho"
|
||||
#define SCNuFAST16 "hu"
|
||||
#define SCNxFAST16 "hx"
|
||||
#define SCNXFAST16 "hX"
|
||||
|
||||
#define SCNo32 "lo"
|
||||
#define SCNu32 "lu"
|
||||
#define SCNx32 "lx"
|
||||
#define SCNX32 "lX"
|
||||
#define SCNoLEAST32 "lo"
|
||||
#define SCNuLEAST32 "lu"
|
||||
#define SCNxLEAST32 "lx"
|
||||
#define SCNXLEAST32 "lX"
|
||||
#define SCNoFAST32 "lo"
|
||||
#define SCNuFAST32 "lu"
|
||||
#define SCNxFAST32 "lx"
|
||||
#define SCNXFAST32 "lX"
|
||||
|
||||
#define SCNo64 "I64o"
|
||||
#define SCNu64 "I64u"
|
||||
#define SCNx64 "I64x"
|
||||
#define SCNX64 "I64X"
|
||||
#define SCNoLEAST64 "I64o"
|
||||
#define SCNuLEAST64 "I64u"
|
||||
#define SCNxLEAST64 "I64x"
|
||||
#define SCNXLEAST64 "I64X"
|
||||
#define SCNoFAST64 "I64o"
|
||||
#define SCNuFAST64 "I64u"
|
||||
#define SCNxFAST64 "I64x"
|
||||
#define SCNXFAST64 "I64X"
|
||||
|
||||
#define SCNoMAX "I64o"
|
||||
#define SCNuMAX "I64u"
|
||||
#define SCNxMAX "I64x"
|
||||
#define SCNXMAX "I64X"
|
||||
|
||||
#ifdef _WIN64 // [
|
||||
# define SCNoPTR "I64o"
|
||||
# define SCNuPTR "I64u"
|
||||
# define SCNxPTR "I64x"
|
||||
# define SCNXPTR "I64X"
|
||||
#else // _WIN64 ][
|
||||
# define SCNoPTR "lo"
|
||||
# define SCNuPTR "lu"
|
||||
# define SCNxPTR "lx"
|
||||
# define SCNXPTR "lX"
|
||||
#endif // _WIN64 ]
|
||||
|
||||
#endif // __STDC_FORMAT_MACROS ]
|
||||
|
||||
// 7.8.2 Functions for greatest-width integer types
|
||||
|
||||
// 7.8.2.1 The imaxabs function
|
||||
#define imaxabs _abs64
|
||||
|
||||
// 7.8.2.2 The imaxdiv function
|
||||
|
||||
// This is modified version of div() function from Microsoft's div.c found
|
||||
// in %MSVC.NET%\crt\src\div.c
|
||||
#ifdef STATIC_IMAXDIV // [
|
||||
static
|
||||
#else // STATIC_IMAXDIV ][
|
||||
_inline
|
||||
#endif // STATIC_IMAXDIV ]
|
||||
imaxdiv_t __cdecl imaxdiv(intmax_t numer, intmax_t denom)
|
||||
{
|
||||
imaxdiv_t result;
|
||||
|
||||
result.quot = numer / denom;
|
||||
result.rem = numer % denom;
|
||||
|
||||
if (numer < 0 && result.rem > 0) {
|
||||
// did division wrong; must fix up
|
||||
++result.quot;
|
||||
result.rem -= denom;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// 7.8.2.3 The strtoimax and strtoumax functions
|
||||
#define strtoimax _strtoi64
|
||||
#define strtoumax _strtoui64
|
||||
|
||||
// 7.8.2.4 The wcstoimax and wcstoumax functions
|
||||
#define wcstoimax _wcstoi64
|
||||
#define wcstoumax _wcstoui64
|
||||
|
||||
|
||||
#endif // _MSC_INTTYPES_H_ ]
|
||||
@@ -0,0 +1,260 @@
|
||||
// ISO C9x compliant stdint.h for Microsoft Visual Studio
|
||||
// Based on ISO/IEC 9899:TC2 Committee draft (May 6, 2005) WG14/N1124
|
||||
//
|
||||
// Copyright (c) 2006-2013 Alexander Chemeris
|
||||
//
|
||||
// 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. Neither the name of the product 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 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.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef _MSC_VER // [
|
||||
#error "Use this header only with Microsoft Visual C++ compilers!"
|
||||
#endif // _MSC_VER ]
|
||||
|
||||
#ifndef _MSC_STDINT_H_ // [
|
||||
#define _MSC_STDINT_H_
|
||||
|
||||
#if _MSC_VER > 1000
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
// miloyip: Originally Visual Studio 2010 uses its own stdint.h. However it generates warning with INT64_C(), so change to use this file for vs2010.
|
||||
#if _MSC_VER >= 1700 // [
|
||||
#include <stdint.h>
|
||||
#else // ] _MSC_VER >= 1700 [
|
||||
|
||||
#include <limits.h>
|
||||
|
||||
// For Visual Studio 6 in C++ mode and for many Visual Studio versions when
|
||||
// compiling for ARM we should wrap <wchar.h> include with 'extern "C++" {}'
|
||||
// or compiler give many errors like this:
|
||||
// error C2733: second C linkage of overloaded function 'wmemchr' not allowed
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
# include <wchar.h>
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
// Define _W64 macros to mark types changing their size, like intptr_t.
|
||||
#ifndef _W64
|
||||
# if !defined(__midl) && (defined(_X86_) || defined(_M_IX86)) && _MSC_VER >= 1300
|
||||
# define _W64 __w64
|
||||
# else
|
||||
# define _W64
|
||||
# endif
|
||||
#endif
|
||||
|
||||
|
||||
// 7.18.1 Integer types
|
||||
|
||||
// 7.18.1.1 Exact-width integer types
|
||||
|
||||
// Visual Studio 6 and Embedded Visual C++ 4 doesn't
|
||||
// realize that, e.g. char has the same size as __int8
|
||||
// so we give up on __intX for them.
|
||||
#if (_MSC_VER < 1300)
|
||||
typedef signed char int8_t;
|
||||
typedef signed short int16_t;
|
||||
typedef signed int int32_t;
|
||||
typedef unsigned char uint8_t;
|
||||
typedef unsigned short uint16_t;
|
||||
typedef unsigned int uint32_t;
|
||||
#else
|
||||
typedef signed __int8 int8_t;
|
||||
typedef signed __int16 int16_t;
|
||||
typedef signed __int32 int32_t;
|
||||
typedef unsigned __int8 uint8_t;
|
||||
typedef unsigned __int16 uint16_t;
|
||||
typedef unsigned __int32 uint32_t;
|
||||
#endif
|
||||
typedef signed __int64 int64_t;
|
||||
typedef unsigned __int64 uint64_t;
|
||||
|
||||
|
||||
// 7.18.1.2 Minimum-width integer types
|
||||
typedef int8_t int_least8_t;
|
||||
typedef int16_t int_least16_t;
|
||||
typedef int32_t int_least32_t;
|
||||
typedef int64_t int_least64_t;
|
||||
typedef uint8_t uint_least8_t;
|
||||
typedef uint16_t uint_least16_t;
|
||||
typedef uint32_t uint_least32_t;
|
||||
typedef uint64_t uint_least64_t;
|
||||
|
||||
// 7.18.1.3 Fastest minimum-width integer types
|
||||
typedef int8_t int_fast8_t;
|
||||
typedef int16_t int_fast16_t;
|
||||
typedef int32_t int_fast32_t;
|
||||
typedef int64_t int_fast64_t;
|
||||
typedef uint8_t uint_fast8_t;
|
||||
typedef uint16_t uint_fast16_t;
|
||||
typedef uint32_t uint_fast32_t;
|
||||
typedef uint64_t uint_fast64_t;
|
||||
|
||||
// 7.18.1.4 Integer types capable of holding object pointers
|
||||
#ifdef _WIN64 // [
|
||||
typedef signed __int64 intptr_t;
|
||||
typedef unsigned __int64 uintptr_t;
|
||||
#else // _WIN64 ][
|
||||
typedef _W64 signed int intptr_t;
|
||||
typedef _W64 unsigned int uintptr_t;
|
||||
#endif // _WIN64 ]
|
||||
|
||||
// 7.18.1.5 Greatest-width integer types
|
||||
typedef int64_t intmax_t;
|
||||
typedef uint64_t uintmax_t;
|
||||
|
||||
|
||||
// 7.18.2 Limits of specified-width integer types
|
||||
|
||||
#if !defined(__cplusplus) || defined(__STDC_LIMIT_MACROS) // [ See footnote 220 at page 257 and footnote 221 at page 259
|
||||
|
||||
// 7.18.2.1 Limits of exact-width integer types
|
||||
#define INT8_MIN ((int8_t)_I8_MIN)
|
||||
#define INT8_MAX _I8_MAX
|
||||
#define INT16_MIN ((int16_t)_I16_MIN)
|
||||
#define INT16_MAX _I16_MAX
|
||||
#define INT32_MIN ((int32_t)_I32_MIN)
|
||||
#define INT32_MAX _I32_MAX
|
||||
#define INT64_MIN ((int64_t)_I64_MIN)
|
||||
#define INT64_MAX _I64_MAX
|
||||
#define UINT8_MAX _UI8_MAX
|
||||
#define UINT16_MAX _UI16_MAX
|
||||
#define UINT32_MAX _UI32_MAX
|
||||
#define UINT64_MAX _UI64_MAX
|
||||
|
||||
// 7.18.2.2 Limits of minimum-width integer types
|
||||
#define INT_LEAST8_MIN INT8_MIN
|
||||
#define INT_LEAST8_MAX INT8_MAX
|
||||
#define INT_LEAST16_MIN INT16_MIN
|
||||
#define INT_LEAST16_MAX INT16_MAX
|
||||
#define INT_LEAST32_MIN INT32_MIN
|
||||
#define INT_LEAST32_MAX INT32_MAX
|
||||
#define INT_LEAST64_MIN INT64_MIN
|
||||
#define INT_LEAST64_MAX INT64_MAX
|
||||
#define UINT_LEAST8_MAX UINT8_MAX
|
||||
#define UINT_LEAST16_MAX UINT16_MAX
|
||||
#define UINT_LEAST32_MAX UINT32_MAX
|
||||
#define UINT_LEAST64_MAX UINT64_MAX
|
||||
|
||||
// 7.18.2.3 Limits of fastest minimum-width integer types
|
||||
#define INT_FAST8_MIN INT8_MIN
|
||||
#define INT_FAST8_MAX INT8_MAX
|
||||
#define INT_FAST16_MIN INT16_MIN
|
||||
#define INT_FAST16_MAX INT16_MAX
|
||||
#define INT_FAST32_MIN INT32_MIN
|
||||
#define INT_FAST32_MAX INT32_MAX
|
||||
#define INT_FAST64_MIN INT64_MIN
|
||||
#define INT_FAST64_MAX INT64_MAX
|
||||
#define UINT_FAST8_MAX UINT8_MAX
|
||||
#define UINT_FAST16_MAX UINT16_MAX
|
||||
#define UINT_FAST32_MAX UINT32_MAX
|
||||
#define UINT_FAST64_MAX UINT64_MAX
|
||||
|
||||
// 7.18.2.4 Limits of integer types capable of holding object pointers
|
||||
#ifdef _WIN64 // [
|
||||
# define INTPTR_MIN INT64_MIN
|
||||
# define INTPTR_MAX INT64_MAX
|
||||
# define UINTPTR_MAX UINT64_MAX
|
||||
#else // _WIN64 ][
|
||||
# define INTPTR_MIN INT32_MIN
|
||||
# define INTPTR_MAX INT32_MAX
|
||||
# define UINTPTR_MAX UINT32_MAX
|
||||
#endif // _WIN64 ]
|
||||
|
||||
// 7.18.2.5 Limits of greatest-width integer types
|
||||
#define INTMAX_MIN INT64_MIN
|
||||
#define INTMAX_MAX INT64_MAX
|
||||
#define UINTMAX_MAX UINT64_MAX
|
||||
|
||||
// 7.18.3 Limits of other integer types
|
||||
|
||||
#ifdef _WIN64 // [
|
||||
# define PTRDIFF_MIN _I64_MIN
|
||||
# define PTRDIFF_MAX _I64_MAX
|
||||
#else // _WIN64 ][
|
||||
# define PTRDIFF_MIN _I32_MIN
|
||||
# define PTRDIFF_MAX _I32_MAX
|
||||
#endif // _WIN64 ]
|
||||
|
||||
#define SIG_ATOMIC_MIN INT_MIN
|
||||
#define SIG_ATOMIC_MAX INT_MAX
|
||||
|
||||
#ifndef SIZE_MAX // [
|
||||
# ifdef _WIN64 // [
|
||||
# define SIZE_MAX _UI64_MAX
|
||||
# else // _WIN64 ][
|
||||
# define SIZE_MAX _UI32_MAX
|
||||
# endif // _WIN64 ]
|
||||
#endif // SIZE_MAX ]
|
||||
|
||||
// WCHAR_MIN and WCHAR_MAX are also defined in <wchar.h>
|
||||
#ifndef WCHAR_MIN // [
|
||||
# define WCHAR_MIN 0
|
||||
#endif // WCHAR_MIN ]
|
||||
#ifndef WCHAR_MAX // [
|
||||
# define WCHAR_MAX _UI16_MAX
|
||||
#endif // WCHAR_MAX ]
|
||||
|
||||
#define WINT_MIN 0
|
||||
#define WINT_MAX _UI16_MAX
|
||||
|
||||
#endif // __STDC_LIMIT_MACROS ]
|
||||
|
||||
|
||||
// 7.18.4 Limits of other integer types
|
||||
|
||||
#if !defined(__cplusplus) || defined(__STDC_CONSTANT_MACROS) // [ See footnote 224 at page 260
|
||||
|
||||
// 7.18.4.1 Macros for minimum-width integer constants
|
||||
|
||||
#define INT8_C(val) val##i8
|
||||
#define INT16_C(val) val##i16
|
||||
#define INT32_C(val) val##i32
|
||||
#define INT64_C(val) val##i64
|
||||
|
||||
#define UINT8_C(val) val##ui8
|
||||
#define UINT16_C(val) val##ui16
|
||||
#define UINT32_C(val) val##ui32
|
||||
#define UINT64_C(val) val##ui64
|
||||
|
||||
// 7.18.4.2 Macros for greatest-width integer constants
|
||||
// These #ifndef's are needed to prevent collisions with <boost/cstdint.hpp>.
|
||||
// Check out Issue 9 for the details.
|
||||
#ifndef INTMAX_C // [
|
||||
# define INTMAX_C INT64_C
|
||||
#endif // INTMAX_C ]
|
||||
#ifndef UINTMAX_C // [
|
||||
# define UINTMAX_C UINT64_C
|
||||
#endif // UINTMAX_C ]
|
||||
|
||||
#endif // __STDC_CONSTANT_MACROS ]
|
||||
|
||||
#endif // _MSC_VER >= 1600 ]
|
||||
|
||||
#endif // _MSC_STDINT_H_ ]
|
||||
@@ -0,0 +1,195 @@
|
||||
#ifndef RAPIDJSON_PRETTYWRITER_H_
|
||||
#define RAPIDJSON_PRETTYWRITER_H_
|
||||
|
||||
#include "writer.h"
|
||||
|
||||
#ifdef __GNUC__
|
||||
RAPIDJSON_DIAG_PUSH
|
||||
RAPIDJSON_DIAG_OFF(effc++)
|
||||
#endif
|
||||
|
||||
namespace rapidjson {
|
||||
|
||||
//! Writer with indentation and spacing.
|
||||
/*!
|
||||
\tparam OutputStream Type of ouptut os.
|
||||
\tparam SourceEncoding Encoding of source string.
|
||||
\tparam TargetEncoding Encoding of output stream.
|
||||
\tparam Allocator Type of allocator for allocating memory of stack.
|
||||
*/
|
||||
template<typename OutputStream, typename SourceEncoding = UTF8<>, typename TargetEncoding = UTF8<>, typename Allocator = MemoryPoolAllocator<> >
|
||||
class PrettyWriter : public Writer<OutputStream, SourceEncoding, TargetEncoding, Allocator> {
|
||||
public:
|
||||
typedef Writer<OutputStream, SourceEncoding, TargetEncoding, Allocator> Base;
|
||||
typedef typename Base::Ch Ch;
|
||||
|
||||
//! Constructor
|
||||
/*! \param os Output stream.
|
||||
\param allocator User supplied allocator. If it is null, it will create a private one.
|
||||
\param levelDepth Initial capacity of stack.
|
||||
*/
|
||||
PrettyWriter(OutputStream& os, Allocator* allocator = 0, size_t levelDepth = Base::kDefaultLevelDepth) :
|
||||
Base(os, allocator, levelDepth), indentChar_(' '), indentCharCount_(4) {}
|
||||
|
||||
//! Overridden for fluent API, see \ref Writer::SetDoublePrecision()
|
||||
PrettyWriter& SetDoublePrecision(int p) { Base::SetDoublePrecision(p); return *this; }
|
||||
|
||||
//! Set custom indentation.
|
||||
/*! \param indentChar Character for indentation. Must be whitespace character (' ', '\\t', '\\n', '\\r').
|
||||
\param indentCharCount Number of indent characters for each indentation level.
|
||||
\note The default indentation is 4 spaces.
|
||||
*/
|
||||
PrettyWriter& SetIndent(Ch indentChar, unsigned indentCharCount) {
|
||||
RAPIDJSON_ASSERT(indentChar == ' ' || indentChar == '\t' || indentChar == '\n' || indentChar == '\r');
|
||||
indentChar_ = indentChar;
|
||||
indentCharCount_ = indentCharCount;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/*! @name Implementation of Handler
|
||||
\see Handler
|
||||
*/
|
||||
//@{
|
||||
|
||||
bool Null() { PrettyPrefix(kNullType); return Base::WriteNull(); }
|
||||
bool Bool(bool b) { PrettyPrefix(b ? kTrueType : kFalseType); return Base::WriteBool(b); }
|
||||
bool Int(int i) { PrettyPrefix(kNumberType); return Base::WriteInt(i); }
|
||||
bool Uint(unsigned u) { PrettyPrefix(kNumberType); return Base::WriteUint(u); }
|
||||
bool Int64(int64_t i64) { PrettyPrefix(kNumberType); return Base::WriteInt64(i64); }
|
||||
bool Uint64(uint64_t u64) { PrettyPrefix(kNumberType); return Base::WriteUint64(u64); }
|
||||
bool Double(double d) { PrettyPrefix(kNumberType); return Base::WriteDouble(d); }
|
||||
|
||||
bool String(const Ch* str, SizeType length, bool copy = false) {
|
||||
(void)copy;
|
||||
PrettyPrefix(kStringType);
|
||||
return Base::WriteString(str, length);
|
||||
}
|
||||
|
||||
bool StartObject() {
|
||||
PrettyPrefix(kObjectType);
|
||||
new (Base::level_stack_.template Push<typename Base::Level>()) typename Base::Level(false);
|
||||
return Base::WriteStartObject();
|
||||
}
|
||||
|
||||
bool EndObject(SizeType memberCount = 0) {
|
||||
(void)memberCount;
|
||||
RAPIDJSON_ASSERT(Base::level_stack_.GetSize() >= sizeof(typename Base::Level));
|
||||
RAPIDJSON_ASSERT(!Base::level_stack_.template Top<typename Base::Level>()->inArray);
|
||||
bool empty = Base::level_stack_.template Pop<typename Base::Level>(1)->valueCount == 0;
|
||||
|
||||
if (!empty) {
|
||||
Base::os_->Put('\n');
|
||||
WriteIndent();
|
||||
}
|
||||
if (!Base::WriteEndObject())
|
||||
return false;
|
||||
if (Base::level_stack_.Empty()) // end of json text
|
||||
Base::os_->Flush();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool StartArray() {
|
||||
PrettyPrefix(kArrayType);
|
||||
new (Base::level_stack_.template Push<typename Base::Level>()) typename Base::Level(true);
|
||||
return Base::WriteStartArray();
|
||||
}
|
||||
|
||||
bool EndArray(SizeType memberCount = 0) {
|
||||
(void)memberCount;
|
||||
RAPIDJSON_ASSERT(Base::level_stack_.GetSize() >= sizeof(typename Base::Level));
|
||||
RAPIDJSON_ASSERT(Base::level_stack_.template Top<typename Base::Level>()->inArray);
|
||||
bool empty = Base::level_stack_.template Pop<typename Base::Level>(1)->valueCount == 0;
|
||||
|
||||
if (!empty) {
|
||||
Base::os_->Put('\n');
|
||||
WriteIndent();
|
||||
}
|
||||
if (!Base::WriteEndArray())
|
||||
return false;
|
||||
if (Base::level_stack_.Empty()) // end of json text
|
||||
Base::os_->Flush();
|
||||
return true;
|
||||
}
|
||||
|
||||
//@}
|
||||
|
||||
/*! @name Convenience extensions */
|
||||
//@{
|
||||
|
||||
//! Simpler but slower overload.
|
||||
bool String(const Ch* str) { return String(str, internal::StrLen(str)); }
|
||||
|
||||
//! Overridden for fluent API, see \ref Writer::Double()
|
||||
bool Double(double d, int precision) {
|
||||
int oldPrecision = Base::GetDoublePrecision();
|
||||
SetDoublePrecision(precision);
|
||||
bool ret = Double(d);
|
||||
SetDoublePrecision(oldPrecision);
|
||||
return ret;
|
||||
}
|
||||
|
||||
//@}
|
||||
protected:
|
||||
void PrettyPrefix(Type type) {
|
||||
(void)type;
|
||||
if (Base::level_stack_.GetSize() != 0) { // this value is not at root
|
||||
typename Base::Level* level = Base::level_stack_.template Top<typename Base::Level>();
|
||||
|
||||
if (level->inArray) {
|
||||
if (level->valueCount > 0) {
|
||||
Base::os_->Put(','); // add comma if it is not the first element in array
|
||||
Base::os_->Put('\n');
|
||||
}
|
||||
else
|
||||
Base::os_->Put('\n');
|
||||
WriteIndent();
|
||||
}
|
||||
else { // in object
|
||||
if (level->valueCount > 0) {
|
||||
if (level->valueCount % 2 == 0) {
|
||||
Base::os_->Put(',');
|
||||
Base::os_->Put('\n');
|
||||
}
|
||||
else {
|
||||
Base::os_->Put(':');
|
||||
Base::os_->Put(' ');
|
||||
}
|
||||
}
|
||||
else
|
||||
Base::os_->Put('\n');
|
||||
|
||||
if (level->valueCount % 2 == 0)
|
||||
WriteIndent();
|
||||
}
|
||||
if (!level->inArray && level->valueCount % 2 == 0)
|
||||
RAPIDJSON_ASSERT(type == kStringType); // if it's in object, then even number should be a name
|
||||
level->valueCount++;
|
||||
}
|
||||
else {
|
||||
RAPIDJSON_ASSERT(type == kObjectType || type == kArrayType);
|
||||
RAPIDJSON_ASSERT(!Base::hasRoot_); // Should only has one and only one root.
|
||||
Base::hasRoot_ = true;
|
||||
}
|
||||
}
|
||||
|
||||
void WriteIndent() {
|
||||
size_t count = (Base::level_stack_.GetSize() / sizeof(typename Base::Level)) * indentCharCount_;
|
||||
PutN(*Base::os_, indentChar_, count);
|
||||
}
|
||||
|
||||
Ch indentChar_;
|
||||
unsigned indentCharCount_;
|
||||
|
||||
private:
|
||||
// Prohibit copy constructor & assignment operator.
|
||||
PrettyWriter(const PrettyWriter&);
|
||||
PrettyWriter& operator=(const PrettyWriter&);
|
||||
};
|
||||
|
||||
} // namespace rapidjson
|
||||
|
||||
#ifdef __GNUC__
|
||||
RAPIDJSON_DIAG_POP
|
||||
#endif
|
||||
|
||||
#endif // RAPIDJSON_RAPIDJSON_H_
|
||||
@@ -0,0 +1,397 @@
|
||||
#ifndef RAPIDJSON_RAPIDJSON_H_
|
||||
#define RAPIDJSON_RAPIDJSON_H_
|
||||
|
||||
// Copyright (c) 2011 Milo Yip (miloyip@gmail.com)
|
||||
// Version 0.1
|
||||
|
||||
/*!\file rapidjson.h
|
||||
\brief common definitions and configuration
|
||||
|
||||
\todo Complete Doxygen documentation for configure macros.
|
||||
*/
|
||||
|
||||
#include <cstdlib> // malloc(), realloc(), free()
|
||||
#include <cstring> // memcpy()
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// RAPIDJSON_NO_INT64DEFINE
|
||||
|
||||
// Here defines int64_t and uint64_t types in global namespace as well as the
|
||||
// (U)INT64_C constant macros.
|
||||
// If user have their own definition, can define RAPIDJSON_NO_INT64DEFINE to disable this.
|
||||
#ifndef RAPIDJSON_NO_INT64DEFINE
|
||||
//!@cond RAPIDJSON_HIDDEN_FROM_DOXYGEN
|
||||
#ifndef __STDC_CONSTANT_MACROS
|
||||
# define __STDC_CONSTANT_MACROS 1 // required by C++ standard
|
||||
#endif
|
||||
#ifdef _MSC_VER
|
||||
#include "msinttypes/stdint.h"
|
||||
#include "msinttypes/inttypes.h"
|
||||
#else
|
||||
// Other compilers should have this.
|
||||
#include <stdint.h>
|
||||
#include <inttypes.h>
|
||||
#endif
|
||||
//!@endcond
|
||||
#endif // RAPIDJSON_NO_INT64TYPEDEF
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// RAPIDJSON_FORCEINLINE
|
||||
|
||||
#ifndef RAPIDJSON_FORCEINLINE
|
||||
#ifdef _MSC_VER
|
||||
#define RAPIDJSON_FORCEINLINE __forceinline
|
||||
#else
|
||||
#define RAPIDJSON_FORCEINLINE
|
||||
#endif
|
||||
#endif // RAPIDJSON_FORCEINLINE
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// RAPIDJSON_ENDIAN
|
||||
#define RAPIDJSON_LITTLEENDIAN 0 //!< Little endian machine
|
||||
#define RAPIDJSON_BIGENDIAN 1 //!< Big endian machine
|
||||
|
||||
//! Endianness of the machine.
|
||||
/*! GCC 4.6 provided macro for detecting endianness of the target machine. But other
|
||||
compilers may not have this. User can define RAPIDJSON_ENDIAN to either
|
||||
\ref RAPIDJSON_LITTLEENDIAN or \ref RAPIDJSON_BIGENDIAN.
|
||||
|
||||
Implemented with reference to
|
||||
https://gcc.gnu.org/onlinedocs/gcc-4.6.0/cpp/Common-Predefined-Macros.html
|
||||
http://www.boost.org/doc/libs/1_42_0/boost/detail/endian.hpp
|
||||
*/
|
||||
#ifndef RAPIDJSON_ENDIAN
|
||||
// Detect with GCC 4.6's macro
|
||||
# ifdef __BYTE_ORDER__
|
||||
# if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
|
||||
# define RAPIDJSON_ENDIAN RAPIDJSON_LITTLEENDIAN
|
||||
# elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
|
||||
# define RAPIDJSON_ENDIAN RAPIDJSON_BIGENDIAN
|
||||
# else
|
||||
# error Unknown machine endianess detected. User needs to define RAPIDJSON_ENDIAN.
|
||||
# endif // __BYTE_ORDER__
|
||||
// Detect with GLIBC's endian.h
|
||||
# elif defined(__GLIBC__)
|
||||
# include <endian.h>
|
||||
# if (__BYTE_ORDER == __LITTLE_ENDIAN)
|
||||
# define RAPIDJSON_ENDIAN RAPIDJSON_LITTLEENDIAN
|
||||
# elif (__BYTE_ORDER == __BIG_ENDIAN)
|
||||
# define RAPIDJSON_ENDIAN RAPIDJSON_BIGENDIAN
|
||||
# else
|
||||
# error Unknown machine endianess detected. User needs to define RAPIDJSON_ENDIAN.
|
||||
# endif // __GLIBC__
|
||||
// Detect with _LITTLE_ENDIAN and _BIG_ENDIAN macro
|
||||
# elif defined(_LITTLE_ENDIAN) && !defined(_BIG_ENDIAN)
|
||||
# define RAPIDJSON_ENDIAN RAPIDJSON_LITTLEENDIAN
|
||||
# elif defined(_BIG_ENDIAN) && !defined(_LITTLE_ENDIAN)
|
||||
# define RAPIDJSON_ENDIAN RAPIDJSON_BIGENDIAN
|
||||
// Detect with architecture macros
|
||||
# elif defined(__sparc) || defined(__sparc__) || defined(_POWER) || defined(__powerpc__) || defined(__ppc__) || defined(__hpux) || defined(__hppa) || defined(_MIPSEB) || defined(_POWER) || defined(__s390__)
|
||||
# define RAPIDJSON_ENDIAN RAPIDJSON_BIGENDIAN
|
||||
# elif defined(__i386__) || defined(__alpha__) || defined(__ia64) || defined(__ia64__) || defined(_M_IX86) || defined(_M_IA64) || defined(_M_ALPHA) || defined(__amd64) || defined(__amd64__) || defined(_M_AMD64) || defined(__x86_64) || defined(__x86_64__) || defined(_M_X64) || defined(__bfin__)
|
||||
# define RAPIDJSON_ENDIAN RAPIDJSON_LITTLEENDIAN
|
||||
# else
|
||||
# error Unknown machine endianess detected. User needs to define RAPIDJSON_ENDIAN.
|
||||
# endif
|
||||
#endif // RAPIDJSON_ENDIAN
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// RAPIDJSON_ALIGNSIZE
|
||||
|
||||
//! Data alignment of the machine.
|
||||
/*!
|
||||
Some machine requires strict data alignment.
|
||||
Currently the default uses 4 bytes alignment. User can customize this.
|
||||
*/
|
||||
#ifndef RAPIDJSON_ALIGN
|
||||
#define RAPIDJSON_ALIGN(x) ((x + 3u) & ~3u)
|
||||
#endif
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// RAPIDJSON_SSE2/RAPIDJSON_SSE42/RAPIDJSON_SIMD
|
||||
|
||||
// Enable SSE2 optimization.
|
||||
//#define RAPIDJSON_SSE2
|
||||
|
||||
// Enable SSE4.2 optimization.
|
||||
//#define RAPIDJSON_SSE42
|
||||
|
||||
#if defined(RAPIDJSON_SSE2) || defined(RAPIDJSON_SSE42)
|
||||
#define RAPIDJSON_SIMD
|
||||
#endif
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// RAPIDJSON_NO_SIZETYPEDEFINE
|
||||
|
||||
#ifndef RAPIDJSON_NO_SIZETYPEDEFINE
|
||||
namespace rapidjson {
|
||||
//! Use 32-bit array/string indices even for 64-bit platform, instead of using size_t.
|
||||
/*! User may override the SizeType by defining RAPIDJSON_NO_SIZETYPEDEFINE.
|
||||
*/
|
||||
typedef unsigned SizeType;
|
||||
} // namespace rapidjson
|
||||
#endif
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// RAPIDJSON_ASSERT
|
||||
|
||||
//! Assertion.
|
||||
/*! By default, rapidjson uses C assert() for assertion.
|
||||
User can override it by defining RAPIDJSON_ASSERT(x) macro.
|
||||
*/
|
||||
#ifndef RAPIDJSON_ASSERT
|
||||
#include <cassert>
|
||||
#define RAPIDJSON_ASSERT(x) assert(x)
|
||||
#endif // RAPIDJSON_ASSERT
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// RAPIDJSON_STATIC_ASSERT
|
||||
|
||||
// Adopt from boost
|
||||
#ifndef RAPIDJSON_STATIC_ASSERT
|
||||
//!@cond RAPIDJSON_HIDDEN_FROM_DOXYGEN
|
||||
namespace rapidjson {
|
||||
|
||||
template <bool x> struct STATIC_ASSERTION_FAILURE;
|
||||
template <> struct STATIC_ASSERTION_FAILURE<true> { enum { value = 1 }; };
|
||||
template<int x> struct StaticAssertTest {};
|
||||
} // namespace rapidjson
|
||||
|
||||
#define RAPIDJSON_JOIN(X, Y) RAPIDJSON_DO_JOIN(X, Y)
|
||||
#define RAPIDJSON_DO_JOIN(X, Y) RAPIDJSON_DO_JOIN2(X, Y)
|
||||
#define RAPIDJSON_DO_JOIN2(X, Y) X##Y
|
||||
|
||||
#if defined(__GNUC__)
|
||||
#define RAPIDJSON_STATIC_ASSERT_UNUSED_ATTRIBUTE __attribute__((unused))
|
||||
#else
|
||||
#define RAPIDJSON_STATIC_ASSERT_UNUSED_ATTRIBUTE
|
||||
#endif
|
||||
//!@endcond
|
||||
|
||||
/*! \def RAPIDJSON_STATIC_ASSERT
|
||||
\brief (internal) macro to check for conditions at compile-time
|
||||
\param x compile-time condition
|
||||
\hideinitializer
|
||||
*/
|
||||
#define RAPIDJSON_STATIC_ASSERT(x) typedef ::rapidjson::StaticAssertTest<\
|
||||
sizeof(::rapidjson::STATIC_ASSERTION_FAILURE<bool(x) >)>\
|
||||
RAPIDJSON_JOIN(StaticAssertTypedef, __LINE__) RAPIDJSON_STATIC_ASSERT_UNUSED_ATTRIBUTE
|
||||
#endif
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Helpers
|
||||
|
||||
//!@cond RAPIDJSON_HIDDEN_FROM_DOXYGEN
|
||||
|
||||
#define RAPIDJSON_MULTILINEMACRO_BEGIN do {
|
||||
#define RAPIDJSON_MULTILINEMACRO_END \
|
||||
} while((void)0, 0)
|
||||
|
||||
// adopted from Boost
|
||||
#define RAPIDJSON_VERSION_CODE(x,y,z) \
|
||||
(((x)*100000) + ((y)*100) + (z))
|
||||
|
||||
// token stringification
|
||||
#define RAPIDJSON_STRINGIFY(x) RAPIDJSON_DO_STRINGIFY(x)
|
||||
#define RAPIDJSON_DO_STRINGIFY(x) #x
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// RAPIDJSON_DIAG_PUSH/POP, RAPIDJSON_DIAG_OFF
|
||||
|
||||
#if defined(__clang__) || (defined(__GNUC__) && RAPIDJSON_VERSION_CODE(__GNUC__,__GNUC_MINOR__,__GNUC_PATCHLEVEL__) >= RAPIDJSON_VERSION_CODE(4,2,0))
|
||||
|
||||
#define RAPIDJSON_PRAGMA(x) _Pragma(RAPIDJSON_STRINGIFY(x))
|
||||
#define RAPIDJSON_DIAG_PRAGMA(x) RAPIDJSON_PRAGMA(GCC diagnostic x)
|
||||
#define RAPIDJSON_DIAG_OFF(x) \
|
||||
RAPIDJSON_DIAG_PRAGMA(ignored RAPIDJSON_STRINGIFY(RAPIDJSON_JOIN(-W,x)))
|
||||
|
||||
// push/pop support in Clang and GCC>=4.6
|
||||
#if defined(__clang__) || (defined(__GNUC__) && RAPIDJSON_VERSION_CODE(__GNUC__,__GNUC_MINOR__,__GNUC_PATCHLEVEL__) >= RAPIDJSON_VERSION_CODE(4,6,0))
|
||||
#define RAPIDJSON_DIAG_PUSH RAPIDJSON_DIAG_PRAGMA(push)
|
||||
#define RAPIDJSON_DIAG_POP RAPIDJSON_DIAG_PRAGMA(pop)
|
||||
#else // GCC >= 4.2, < 4.6
|
||||
#define RAPIDJSON_DIAG_PUSH /* ignored */
|
||||
#define RAPIDJSON_DIAG_POP /* ignored */
|
||||
#endif
|
||||
|
||||
#elif defined(_MSC_VER)
|
||||
|
||||
// pragma (MSVC specific)
|
||||
#define RAPIDJSON_PRAGMA(x) __pragma(x)
|
||||
#define RAPIDJSON_DIAG_PRAGMA(x) RAPIDJSON_PRAGMA(warning(x))
|
||||
|
||||
#define RAPIDJSON_DIAG_OFF(x) RAPIDJSON_DIAG_PRAGMA(disable: x)
|
||||
#define RAPIDJSON_DIAG_PUSH RAPIDJSON_DIAG_PRAGMA(push)
|
||||
#define RAPIDJSON_DIAG_POP RAPIDJSON_DIAG_PRAGMA(pop)
|
||||
|
||||
#else
|
||||
|
||||
#define RAPIDJSON_DIAG_OFF(x) /* ignored */
|
||||
#define RAPIDJSON_DIAG_PUSH /* ignored */
|
||||
#define RAPIDJSON_DIAG_POP /* ignored */
|
||||
|
||||
#endif // RAPIDJSON_DIAG_*
|
||||
|
||||
//!@endcond
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Allocators and Encodings
|
||||
|
||||
#include "allocators.h"
|
||||
#include "encodings.h"
|
||||
|
||||
//! main RapidJSON namespace
|
||||
namespace rapidjson {
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Stream
|
||||
|
||||
/*! \class rapidjson::Stream
|
||||
\brief Concept for reading and writing characters.
|
||||
|
||||
For read-only stream, no need to implement PutBegin(), Put(), Flush() and PutEnd().
|
||||
|
||||
For write-only stream, only need to implement Put() and Flush().
|
||||
|
||||
\code
|
||||
concept Stream {
|
||||
typename Ch; //!< Character type of the stream.
|
||||
|
||||
//! Read the current character from stream without moving the read cursor.
|
||||
Ch Peek() const;
|
||||
|
||||
//! Read the current character from stream and moving the read cursor to next character.
|
||||
Ch Take();
|
||||
|
||||
//! Get the current read cursor.
|
||||
//! \return Number of characters read from start.
|
||||
size_t Tell();
|
||||
|
||||
//! Begin writing operation at the current read pointer.
|
||||
//! \return The begin writer pointer.
|
||||
Ch* PutBegin();
|
||||
|
||||
//! Write a character.
|
||||
void Put(Ch c);
|
||||
|
||||
//! Flush the buffer.
|
||||
void Flush();
|
||||
|
||||
//! End the writing operation.
|
||||
//! \param begin The begin write pointer returned by PutBegin().
|
||||
//! \return Number of characters written.
|
||||
size_t PutEnd(Ch* begin);
|
||||
}
|
||||
\endcode
|
||||
*/
|
||||
|
||||
//! Provides additional information for stream.
|
||||
/*!
|
||||
By using traits pattern, this type provides a default configuration for stream.
|
||||
For custom stream, this type can be specialized for other configuration.
|
||||
See TEST(Reader, CustomStringStream) in readertest.cpp for example.
|
||||
*/
|
||||
template<typename Stream>
|
||||
struct StreamTraits {
|
||||
//! Whether to make local copy of stream for optimization during parsing.
|
||||
/*!
|
||||
By default, for safety, streams do not use local copy optimization.
|
||||
Stream that can be copied fast should specialize this, like StreamTraits<StringStream>.
|
||||
*/
|
||||
enum { copyOptimization = 0 };
|
||||
};
|
||||
|
||||
//! Put N copies of a character to a stream.
|
||||
template<typename Stream, typename Ch>
|
||||
inline void PutN(Stream& stream, Ch c, size_t n) {
|
||||
for (size_t i = 0; i < n; i++)
|
||||
stream.Put(c);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// StringStream
|
||||
|
||||
//! Read-only string stream.
|
||||
/*! \note implements Stream concept
|
||||
*/
|
||||
template <typename Encoding>
|
||||
struct GenericStringStream {
|
||||
typedef typename Encoding::Ch Ch;
|
||||
|
||||
GenericStringStream(const Ch *src) : src_(src), head_(src) {}
|
||||
|
||||
Ch Peek() const { return *src_; }
|
||||
Ch Take() { return *src_++; }
|
||||
size_t Tell() const { return static_cast<size_t>(src_ - head_); }
|
||||
|
||||
Ch* PutBegin() { RAPIDJSON_ASSERT(false); return 0; }
|
||||
void Put(Ch) { RAPIDJSON_ASSERT(false); }
|
||||
void Flush() { RAPIDJSON_ASSERT(false); }
|
||||
size_t PutEnd(Ch*) { RAPIDJSON_ASSERT(false); return 0; }
|
||||
|
||||
const Ch* src_; //!< Current read position.
|
||||
const Ch* head_; //!< Original head of the string.
|
||||
};
|
||||
|
||||
template <typename Encoding>
|
||||
struct StreamTraits<GenericStringStream<Encoding> > {
|
||||
enum { copyOptimization = 1 };
|
||||
};
|
||||
|
||||
//! String stream with UTF8 encoding.
|
||||
typedef GenericStringStream<UTF8<> > StringStream;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// InsituStringStream
|
||||
|
||||
//! A read-write string stream.
|
||||
/*! This string stream is particularly designed for in-situ parsing.
|
||||
\note implements Stream concept
|
||||
*/
|
||||
template <typename Encoding>
|
||||
struct GenericInsituStringStream {
|
||||
typedef typename Encoding::Ch Ch;
|
||||
|
||||
GenericInsituStringStream(Ch *src) : src_(src), dst_(0), head_(src) {}
|
||||
|
||||
// Read
|
||||
Ch Peek() { return *src_; }
|
||||
Ch Take() { return *src_++; }
|
||||
size_t Tell() { return static_cast<size_t>(src_ - head_); }
|
||||
|
||||
// Write
|
||||
Ch* PutBegin() { return dst_ = src_; }
|
||||
void Put(Ch c) { RAPIDJSON_ASSERT(dst_ != 0); *dst_++ = c; }
|
||||
void Flush() {}
|
||||
size_t PutEnd(Ch* begin) { return static_cast<size_t>(dst_ - begin); }
|
||||
|
||||
Ch* src_;
|
||||
Ch* dst_;
|
||||
Ch* head_;
|
||||
};
|
||||
|
||||
template <typename Encoding>
|
||||
struct StreamTraits<GenericInsituStringStream<Encoding> > {
|
||||
enum { copyOptimization = 1 };
|
||||
};
|
||||
|
||||
//! Insitu string stream with UTF8 encoding.
|
||||
typedef GenericInsituStringStream<UTF8<> > InsituStringStream;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Type
|
||||
|
||||
//! Type of JSON value
|
||||
enum Type {
|
||||
kNullType = 0, //!< null
|
||||
kFalseType = 1, //!< false
|
||||
kTrueType = 2, //!< true
|
||||
kObjectType = 3, //!< object
|
||||
kArrayType = 4, //!< array
|
||||
kStringType = 5, //!< string
|
||||
kNumberType = 6 //!< number
|
||||
};
|
||||
|
||||
} // namespace rapidjson
|
||||
|
||||
#endif // RAPIDJSON_RAPIDJSON_H_
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,51 @@
|
||||
#ifndef RAPIDJSON_STRINGBUFFER_H_
|
||||
#define RAPIDJSON_STRINGBUFFER_H_
|
||||
|
||||
#include "rapidjson.h"
|
||||
#include "internal/stack.h"
|
||||
|
||||
namespace rapidjson {
|
||||
|
||||
//! Represents an in-memory output stream.
|
||||
/*!
|
||||
\tparam Encoding Encoding of the stream.
|
||||
\tparam Allocator type for allocating memory buffer.
|
||||
\note implements Stream concept
|
||||
*/
|
||||
template <typename Encoding, typename Allocator = CrtAllocator>
|
||||
struct GenericStringBuffer {
|
||||
typedef typename Encoding::Ch Ch;
|
||||
|
||||
GenericStringBuffer(Allocator* allocator = 0, size_t capacity = kDefaultCapacity) : stack_(allocator, capacity) {}
|
||||
|
||||
void Put(Ch c) { *stack_.template Push<Ch>() = c; }
|
||||
void Flush() {}
|
||||
|
||||
void Clear() { stack_.Clear(); }
|
||||
|
||||
const Ch* GetString() const {
|
||||
// Push and pop a null terminator. This is safe.
|
||||
*stack_.template Push<Ch>() = '\0';
|
||||
stack_.template Pop<Ch>(1);
|
||||
|
||||
return stack_.template Bottom<Ch>();
|
||||
}
|
||||
|
||||
size_t GetSize() const { return stack_.GetSize(); }
|
||||
|
||||
static const size_t kDefaultCapacity = 256;
|
||||
mutable internal::Stack<Allocator> stack_;
|
||||
};
|
||||
|
||||
//! String buffer with UTF8 encoding
|
||||
typedef GenericStringBuffer<UTF8<> > StringBuffer;
|
||||
|
||||
//! Implement specialized version of PutN() with memset() for better performance.
|
||||
template<>
|
||||
inline void PutN(GenericStringBuffer<UTF8<> >& stream, char c, size_t n) {
|
||||
memset(stream.stack_.Push<char>(n), c, n * sizeof(c));
|
||||
}
|
||||
|
||||
} // namespace rapidjson
|
||||
|
||||
#endif // RAPIDJSON_STRINGBUFFER_H_
|
||||
@@ -0,0 +1,387 @@
|
||||
#ifndef RAPIDJSON_WRITER_H_
|
||||
#define RAPIDJSON_WRITER_H_
|
||||
|
||||
#include "rapidjson.h"
|
||||
#include "internal/stack.h"
|
||||
#include "internal/strfunc.h"
|
||||
#include <cstdio> // snprintf() or _sprintf_s()
|
||||
#include <new> // placement new
|
||||
|
||||
#ifdef _MSC_VER
|
||||
RAPIDJSON_DIAG_PUSH
|
||||
RAPIDJSON_DIAG_OFF(4127) // conditional expression is constant
|
||||
#endif
|
||||
|
||||
namespace rapidjson {
|
||||
|
||||
//! JSON writer
|
||||
/*! Writer implements the concept Handler.
|
||||
It generates JSON text by events to an output os.
|
||||
|
||||
User may programmatically calls the functions of a writer to generate JSON text.
|
||||
|
||||
On the other side, a writer can also be passed to objects that generates events,
|
||||
|
||||
for example Reader::Parse() and Document::Accept().
|
||||
|
||||
\tparam OutputStream Type of output stream.
|
||||
\tparam SourceEncoding Encoding of source string.
|
||||
\tparam TargetEncoding Encoding of output stream.
|
||||
\tparam Allocator Type of allocator for allocating memory of stack.
|
||||
\note implements Handler concept
|
||||
*/
|
||||
template<typename OutputStream, typename SourceEncoding = UTF8<>, typename TargetEncoding = UTF8<>, typename Allocator = MemoryPoolAllocator<> >
|
||||
class Writer {
|
||||
public:
|
||||
typedef typename SourceEncoding::Ch Ch;
|
||||
|
||||
//! Constructor
|
||||
/*! \param os Output stream.
|
||||
\param allocator User supplied allocator. If it is null, it will create a private one.
|
||||
\param levelDepth Initial capacity of stack.
|
||||
*/
|
||||
Writer(OutputStream& os, Allocator* allocator = 0, size_t levelDepth = kDefaultLevelDepth) :
|
||||
os_(&os), level_stack_(allocator, levelDepth * sizeof(Level)),
|
||||
doublePrecision_(kDefaultDoublePrecision), hasRoot_(false) {}
|
||||
|
||||
//! Reset the writer with a new stream.
|
||||
/*!
|
||||
This function reset the writer with a new stream and default settings,
|
||||
in order to make a Writer object reusable for output multiple JSONs.
|
||||
|
||||
\param os New output stream.
|
||||
\code
|
||||
Writer<OutputStream> writer(os1);
|
||||
writer.StartObject();
|
||||
// ...
|
||||
writer.EndObject();
|
||||
|
||||
writer.Reset(os2);
|
||||
writer.StartObject();
|
||||
// ...
|
||||
writer.EndObject();
|
||||
\endcode
|
||||
*/
|
||||
void Reset(OutputStream& os) {
|
||||
os_ = &os;
|
||||
doublePrecision_ = kDefaultDoublePrecision;
|
||||
hasRoot_ = false;
|
||||
level_stack_.Clear();
|
||||
}
|
||||
|
||||
//! Checks whether the output is a complete JSON.
|
||||
/*!
|
||||
A complete JSON has a complete root object or array.
|
||||
*/
|
||||
bool IsComplete() const {
|
||||
return hasRoot_ && level_stack_.Empty();
|
||||
}
|
||||
|
||||
//! Set the number of significant digits for \c double values
|
||||
/*! When writing a \c double value to the \c OutputStream, the number
|
||||
of significant digits is limited to 6 by default.
|
||||
\param p maximum number of significant digits (default: 6)
|
||||
\return The Writer itself for fluent API.
|
||||
*/
|
||||
Writer& SetDoublePrecision(int p = kDefaultDoublePrecision) {
|
||||
if (p < 0) p = kDefaultDoublePrecision; // negative precision is ignored
|
||||
doublePrecision_ = p;
|
||||
return *this;
|
||||
}
|
||||
|
||||
//! \see SetDoublePrecision()
|
||||
int GetDoublePrecision() const { return doublePrecision_; }
|
||||
|
||||
/*!@name Implementation of Handler
|
||||
\see Handler
|
||||
*/
|
||||
//@{
|
||||
|
||||
bool Null() { Prefix(kNullType); return WriteNull(); }
|
||||
bool Bool(bool b) { Prefix(b ? kTrueType : kFalseType); return WriteBool(b); }
|
||||
bool Int(int i) { Prefix(kNumberType); return WriteInt(i); }
|
||||
bool Uint(unsigned u) { Prefix(kNumberType); return WriteUint(u); }
|
||||
bool Int64(int64_t i64) { Prefix(kNumberType); return WriteInt64(i64); }
|
||||
bool Uint64(uint64_t u64) { Prefix(kNumberType); return WriteUint64(u64); }
|
||||
|
||||
//! Writes the given \c double value to the stream
|
||||
/*!
|
||||
The number of significant digits (the precision) to be written
|
||||
can be set by \ref SetDoublePrecision() for the Writer:
|
||||
\code
|
||||
Writer<...> writer(...);
|
||||
writer.SetDoublePrecision(12).Double(M_PI);
|
||||
\endcode
|
||||
\param d The value to be written.
|
||||
\return Whether it is succeed.
|
||||
*/
|
||||
bool Double(double d) { Prefix(kNumberType); return WriteDouble(d); }
|
||||
|
||||
bool String(const Ch* str, SizeType length, bool copy = false) {
|
||||
(void)copy;
|
||||
Prefix(kStringType);
|
||||
return WriteString(str, length);
|
||||
}
|
||||
|
||||
bool StartObject() {
|
||||
Prefix(kObjectType);
|
||||
new (level_stack_.template Push<Level>()) Level(false);
|
||||
return WriteStartObject();
|
||||
}
|
||||
|
||||
bool EndObject(SizeType memberCount = 0) {
|
||||
(void)memberCount;
|
||||
RAPIDJSON_ASSERT(level_stack_.GetSize() >= sizeof(Level));
|
||||
RAPIDJSON_ASSERT(!level_stack_.template Top<Level>()->inArray);
|
||||
level_stack_.template Pop<Level>(1);
|
||||
bool ret = WriteEndObject();
|
||||
if (level_stack_.Empty()) // end of json text
|
||||
os_->Flush();
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool StartArray() {
|
||||
Prefix(kArrayType);
|
||||
new (level_stack_.template Push<Level>()) Level(true);
|
||||
return WriteStartArray();
|
||||
}
|
||||
|
||||
bool EndArray(SizeType elementCount = 0) {
|
||||
(void)elementCount;
|
||||
RAPIDJSON_ASSERT(level_stack_.GetSize() >= sizeof(Level));
|
||||
RAPIDJSON_ASSERT(level_stack_.template Top<Level>()->inArray);
|
||||
level_stack_.template Pop<Level>(1);
|
||||
bool ret = WriteEndArray();
|
||||
if (level_stack_.Empty()) // end of json text
|
||||
os_->Flush();
|
||||
return ret;
|
||||
}
|
||||
//@}
|
||||
|
||||
/*! @name Convenience extensions */
|
||||
//@{
|
||||
|
||||
//! Writes the given \c double value to the stream (explicit precision)
|
||||
/*!
|
||||
The currently set double precision is ignored in favor of the explicitly
|
||||
given precision for this value.
|
||||
\see Double(), SetDoublePrecision(), GetDoublePrecision()
|
||||
\param d The value to be written
|
||||
\param precision The number of significant digits for this value
|
||||
\return Whether it is succeeded.
|
||||
*/
|
||||
bool Double(double d, int precision) {
|
||||
int oldPrecision = GetDoublePrecision();
|
||||
SetDoublePrecision(precision);
|
||||
bool ret = Double(d);
|
||||
SetDoublePrecision(oldPrecision);
|
||||
return ret;
|
||||
}
|
||||
|
||||
//! Simpler but slower overload.
|
||||
bool String(const Ch* str) { return String(str, internal::StrLen(str)); }
|
||||
|
||||
//@}
|
||||
|
||||
protected:
|
||||
//! Information for each nested level
|
||||
struct Level {
|
||||
Level(bool inArray_) : valueCount(0), inArray(inArray_) {}
|
||||
size_t valueCount; //!< number of values in this level
|
||||
bool inArray; //!< true if in array, otherwise in object
|
||||
};
|
||||
|
||||
static const size_t kDefaultLevelDepth = 32;
|
||||
|
||||
bool WriteNull() {
|
||||
os_->Put('n'); os_->Put('u'); os_->Put('l'); os_->Put('l'); return true;
|
||||
}
|
||||
|
||||
bool WriteBool(bool b) {
|
||||
if (b) {
|
||||
os_->Put('t'); os_->Put('r'); os_->Put('u'); os_->Put('e');
|
||||
}
|
||||
else {
|
||||
os_->Put('f'); os_->Put('a'); os_->Put('l'); os_->Put('s'); os_->Put('e');
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool WriteInt(int i) {
|
||||
if (i < 0) {
|
||||
os_->Put('-');
|
||||
i = -i;
|
||||
}
|
||||
return WriteUint((unsigned)i);
|
||||
}
|
||||
|
||||
bool WriteUint(unsigned u) {
|
||||
char buffer[10];
|
||||
char *p = buffer;
|
||||
do {
|
||||
*p++ = char(u % 10) + '0';
|
||||
u /= 10;
|
||||
} while (u > 0);
|
||||
|
||||
do {
|
||||
--p;
|
||||
os_->Put(*p);
|
||||
} while (p != buffer);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool WriteInt64(int64_t i64) {
|
||||
if (i64 < 0) {
|
||||
os_->Put('-');
|
||||
i64 = -i64;
|
||||
}
|
||||
WriteUint64((uint64_t)i64);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool WriteUint64(uint64_t u64) {
|
||||
char buffer[20];
|
||||
char *p = buffer;
|
||||
do {
|
||||
*p++ = char(u64 % 10) + '0';
|
||||
u64 /= 10;
|
||||
} while (u64 > 0);
|
||||
|
||||
do {
|
||||
--p;
|
||||
os_->Put(*p);
|
||||
} while (p != buffer);
|
||||
return true;
|
||||
}
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#define RAPIDJSON_SNPRINTF sprintf_s
|
||||
#else
|
||||
#define RAPIDJSON_SNPRINTF snprintf
|
||||
#endif
|
||||
|
||||
//! \todo Optimization with custom double-to-string converter.
|
||||
bool WriteDouble(double d) {
|
||||
char buffer[100];
|
||||
int ret = RAPIDJSON_SNPRINTF(buffer, sizeof(buffer), "%.*g", doublePrecision_, d);
|
||||
RAPIDJSON_ASSERT(ret >= 1);
|
||||
for (int i = 0; i < ret; i++)
|
||||
os_->Put(buffer[i]);
|
||||
return true;
|
||||
}
|
||||
#undef RAPIDJSON_SNPRINTF
|
||||
|
||||
bool WriteString(const Ch* str, SizeType length) {
|
||||
static const char hexDigits[16] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
|
||||
static const char escape[256] = {
|
||||
#define Z16 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
|
||||
//0 1 2 3 4 5 6 7 8 9 A B C D E F
|
||||
'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'b', 't', 'n', 'u', 'f', 'r', 'u', 'u', // 00
|
||||
'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', // 10
|
||||
0, 0, '"', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 20
|
||||
Z16, Z16, // 30~4F
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,'\\', 0, 0, 0, // 50
|
||||
Z16, Z16, Z16, Z16, Z16, Z16, Z16, Z16, Z16, Z16 // 60~FF
|
||||
#undef Z16
|
||||
};
|
||||
|
||||
os_->Put('\"');
|
||||
GenericStringStream<SourceEncoding> is(str);
|
||||
while (is.Tell() < length) {
|
||||
const Ch c = is.Peek();
|
||||
if (!TargetEncoding::supportUnicode && (unsigned)c >= 0x80) {
|
||||
// Unicode escaping
|
||||
unsigned codepoint;
|
||||
if (!SourceEncoding::Decode(is, &codepoint))
|
||||
return false;
|
||||
os_->Put('\\');
|
||||
os_->Put('u');
|
||||
if (codepoint <= 0xD7FF || (codepoint >= 0xE000 && codepoint <= 0xFFFF)) {
|
||||
os_->Put(hexDigits[(codepoint >> 12) & 15]);
|
||||
os_->Put(hexDigits[(codepoint >> 8) & 15]);
|
||||
os_->Put(hexDigits[(codepoint >> 4) & 15]);
|
||||
os_->Put(hexDigits[(codepoint ) & 15]);
|
||||
}
|
||||
else if (codepoint >= 0x010000 && codepoint <= 0x10FFFF) {
|
||||
// Surrogate pair
|
||||
unsigned s = codepoint - 0x010000;
|
||||
unsigned lead = (s >> 10) + 0xD800;
|
||||
unsigned trail = (s & 0x3FF) + 0xDC00;
|
||||
os_->Put(hexDigits[(lead >> 12) & 15]);
|
||||
os_->Put(hexDigits[(lead >> 8) & 15]);
|
||||
os_->Put(hexDigits[(lead >> 4) & 15]);
|
||||
os_->Put(hexDigits[(lead ) & 15]);
|
||||
os_->Put('\\');
|
||||
os_->Put('u');
|
||||
os_->Put(hexDigits[(trail >> 12) & 15]);
|
||||
os_->Put(hexDigits[(trail >> 8) & 15]);
|
||||
os_->Put(hexDigits[(trail >> 4) & 15]);
|
||||
os_->Put(hexDigits[(trail ) & 15]);
|
||||
}
|
||||
else
|
||||
return false; // invalid code point
|
||||
}
|
||||
else if ((sizeof(Ch) == 1 || (unsigned)c < 256) && escape[(unsigned char)c]) {
|
||||
is.Take();
|
||||
os_->Put('\\');
|
||||
os_->Put(escape[(unsigned char)c]);
|
||||
if (escape[(unsigned char)c] == 'u') {
|
||||
os_->Put('0');
|
||||
os_->Put('0');
|
||||
os_->Put(hexDigits[(unsigned char)c >> 4]);
|
||||
os_->Put(hexDigits[(unsigned char)c & 0xF]);
|
||||
}
|
||||
}
|
||||
else
|
||||
Transcoder<SourceEncoding, TargetEncoding>::Transcode(is, *os_);
|
||||
}
|
||||
os_->Put('\"');
|
||||
return true;
|
||||
}
|
||||
|
||||
bool WriteStartObject() { os_->Put('{'); return true; }
|
||||
bool WriteEndObject() { os_->Put('}'); return true; }
|
||||
bool WriteStartArray() { os_->Put('['); return true; }
|
||||
bool WriteEndArray() { os_->Put(']'); return true; }
|
||||
|
||||
void Prefix(Type type) {
|
||||
(void)type;
|
||||
if (level_stack_.GetSize() != 0) { // this value is not at root
|
||||
Level* level = level_stack_.template Top<Level>();
|
||||
if (level->valueCount > 0) {
|
||||
if (level->inArray)
|
||||
os_->Put(','); // add comma if it is not the first element in array
|
||||
else // in object
|
||||
os_->Put((level->valueCount % 2 == 0) ? ',' : ':');
|
||||
}
|
||||
if (!level->inArray && level->valueCount % 2 == 0)
|
||||
RAPIDJSON_ASSERT(type == kStringType); // if it's in object, then even number should be a name
|
||||
level->valueCount++;
|
||||
}
|
||||
else {
|
||||
RAPIDJSON_ASSERT(type == kObjectType || type == kArrayType);
|
||||
RAPIDJSON_ASSERT(!hasRoot_); // Should only has one and only one root.
|
||||
hasRoot_ = true;
|
||||
}
|
||||
}
|
||||
|
||||
OutputStream* os_;
|
||||
internal::Stack<Allocator> level_stack_;
|
||||
int doublePrecision_;
|
||||
bool hasRoot_;
|
||||
|
||||
static const int kDefaultDoublePrecision = 6;
|
||||
|
||||
private:
|
||||
// Prohibit copy constructor & assignment operator.
|
||||
Writer(const Writer&);
|
||||
Writer& operator=(const Writer&);
|
||||
};
|
||||
|
||||
} // namespace rapidjson
|
||||
|
||||
#ifdef _MSC_VER
|
||||
RAPIDJSON_DIAG_POP
|
||||
#endif
|
||||
|
||||
#endif // RAPIDJSON_RAPIDJSON_H_
|
||||
+6
-16
@@ -55,7 +55,6 @@ RULE_REAL(Character, AAExpMultiplier, 0.5)
|
||||
RULE_REAL(Character, GroupExpMultiplier, 0.5)
|
||||
RULE_REAL(Character, RaidExpMultiplier, 0.2)
|
||||
RULE_BOOL(Character, UseXPConScaling, true)
|
||||
RULE_INT(Character, ShowExpValues, 0) //0 - normal, 1 - Show raw experience values, 2 - Show raw experience values AND percent.
|
||||
RULE_INT(Character, LightBlueModifier, 40)
|
||||
RULE_INT(Character, BlueModifier, 90)
|
||||
RULE_INT(Character, WhiteModifier, 100)
|
||||
@@ -145,9 +144,6 @@ RULE_BOOL(Character, RestrictSpellScribing, false) // Restricts spell scribing t
|
||||
RULE_BOOL(Character, UseStackablePickPocketing, true) // Allows stackable pickpocketed items to stack instead of only being allowed in empty inventory slots
|
||||
RULE_BOOL(Character, EnableAvoidanceCap, false)
|
||||
RULE_INT(Character, AvoidanceCap, 750) // 750 Is a pretty good value, seen people dodge all attacks beyond 1,000 Avoidance
|
||||
RULE_BOOL(Character, AllowMQTarget, false) // Disables putting players in the 'hackers' list for targeting beyond the clip plane or attempting to target something untargetable
|
||||
RULE_BOOL(Character, UseOldBindWound, false) // Uses the original bind wound behavior
|
||||
RULE_BOOL(Character, GrantHoTTOnCreate, false) // Grant Health of Target's Target leadership AA on character creation
|
||||
RULE_CATEGORY_END()
|
||||
|
||||
RULE_CATEGORY(Mercs)
|
||||
@@ -209,7 +205,6 @@ RULE_INT(World, ExemptMaxClientsStatus, -1) // Exempt accounts from the MaxClien
|
||||
RULE_INT(World, AddMaxClientsPerIP, -1) // Maximum number of clients allowed to connect per IP address if account status is < ExemptMaxClientsStatus. Default value: -1 (feature disabled)
|
||||
RULE_INT(World, AddMaxClientsStatus, -1) // Accounts with status >= this rule will be allowed to use the amount of accounts defined in the AddMaxClientsPerIP. Default value: -1 (feature disabled)
|
||||
RULE_BOOL(World, MaxClientsSetByStatus, false) // If True, IP Limiting will be set to the status on the account as long as the status is > MaxClientsPerIP
|
||||
RULE_BOOL(World, EnableIPExemptions, false) // If True, ip_exemptions table is used, if there is no entry for the IP it will default to RuleI(World, MaxClientsPerIP)
|
||||
RULE_BOOL(World, ClearTempMerchantlist, true) // Clears temp merchant items when world boots.
|
||||
RULE_BOOL(World, DeleteStaleCorpeBackups, true) // Deletes stale corpse backups older than 2 weeks.
|
||||
RULE_INT(World, AccountSessionLimit, -1) //Max number of characters allowed on at once from a single account (-1 is disabled)
|
||||
@@ -257,7 +252,6 @@ RULE_INT(Zone, WeatherTimer, 600) // Weather timer when no duration is available
|
||||
RULE_BOOL(Zone, EnableLoggedOffReplenishments, true)
|
||||
RULE_INT(Zone, MinOfflineTimeToReplenishments, 21600) // 21600 seconds is 6 Hours
|
||||
RULE_BOOL(Zone, UseZoneController, true) // Enables the ability to use persistent quest based zone controllers (zone_controller.pl/lua)
|
||||
RULE_BOOL(Zone, EnableZoneControllerGlobals, false) // Enables the ability to use quest globals with the zone controller NPC
|
||||
RULE_CATEGORY_END()
|
||||
|
||||
RULE_CATEGORY(Map)
|
||||
@@ -333,11 +327,11 @@ RULE_INT(Spells, SacrificeMinLevel, 46) //first level Sacrifice will work on
|
||||
RULE_INT(Spells, SacrificeMaxLevel, 69) //last level Sacrifice will work on
|
||||
RULE_INT(Spells, SacrificeItemID, 9963) //Item ID of the item Sacrifice will return (defaults to an EE)
|
||||
RULE_BOOL(Spells, EnableSpellGlobals, false) // If Enabled, spells check the spell_globals table and compare character data from the quest globals before allowing that spell to scribe with scribespells
|
||||
RULE_INT(Spells, MaxBuffSlotsNPC, 60) // default to Tit's limit
|
||||
RULE_INT(Spells, MaxSongSlotsNPC, 0) // NPCs don't have songs ...
|
||||
RULE_INT(Spells, MaxDiscSlotsNPC, 0) // NPCs don't have discs ...
|
||||
RULE_INT(Spells, MaxTotalSlotsNPC, 60) // default to Tit's limit
|
||||
RULE_INT(Spells, MaxTotalSlotsPET, 30) // default to Tit's limit
|
||||
RULE_INT(Spells, MaxBuffSlotsNPC, 25)
|
||||
RULE_INT(Spells, MaxSongSlotsNPC, 10)
|
||||
RULE_INT(Spells, MaxDiscSlotsNPC, 1)
|
||||
RULE_INT(Spells, MaxTotalSlotsNPC, 36)
|
||||
RULE_INT(Spells, MaxTotalSlotsPET, 30) // do not set this higher than 25 until the player profile is removed from the blob
|
||||
RULE_BOOL (Spells, EnableBlockedBuffs, true)
|
||||
RULE_INT(Spells, ReflectType, 1) //0 = disabled, 1 = single target player spells only, 2 = all player spells, 3 = all single target spells, 4 = all spells
|
||||
RULE_INT(Spells, VirusSpreadDistance, 30) // The distance a viral spell will jump to its next victim
|
||||
@@ -388,7 +382,6 @@ RULE_BOOL(Spells, AlwaysSendTargetsBuffs, false) // ignore LAA level if true
|
||||
RULE_BOOL(Spells, FlatItemExtraSpellAmt, false) // allow SpellDmg stat to affect all spells, regardless of cast time/cooldown/etc
|
||||
RULE_BOOL(Spells, IgnoreSpellDmgLvlRestriction, false) // ignore the 5 level spread on applying SpellDmg
|
||||
RULE_BOOL(Spells, AllowItemTGB, false) // TGB doesn't work with items on live, custom servers want it though
|
||||
RULE_BOOL(Spells, NPCInnateProcOverride, true) // NPC innate procs override the target type to single target.
|
||||
RULE_CATEGORY_END()
|
||||
|
||||
RULE_CATEGORY(Combat)
|
||||
@@ -491,8 +484,6 @@ RULE_BOOL(Combat, UseLiveCombatRounds, true) // turn this false if you don't wan
|
||||
RULE_INT(Combat, NPCAssistCap, 5) // Maxiumium number of NPCs that will assist another NPC at once
|
||||
RULE_INT(Combat, NPCAssistCapTimer, 6000) // Time in milliseconds a NPC will take to clear assist aggro cap space
|
||||
RULE_BOOL(Combat, UseRevampHandToHand, false) // use h2h revamped dmg/delays I believe this was implemented during SoF
|
||||
RULE_BOOL(Combat, ClassicMasterWu, false) // classic master wu uses a random special, modern doesn't
|
||||
RULE_INT(Combat, LevelToStopDamageCaps, 0) // 1 will effectively disable them, 20 should give basically same results as old incorrect system
|
||||
RULE_CATEGORY_END()
|
||||
|
||||
RULE_CATEGORY(NPC)
|
||||
@@ -557,13 +548,12 @@ RULE_REAL(Bots, ManaRegen, 2.0) // Adjust mana regen for bots, 1 is fast and hig
|
||||
RULE_BOOL(Bots, PreferNoManaCommandSpells, true) // Give sorting priority to newer no-mana spells (i.e., 'Bind Affinity')
|
||||
RULE_BOOL(Bots, QuestableSpawnLimit, false) // Optional quest method to manage bot spawn limits using the quest_globals name bot_spawn_limit, see: /bazaar/Aediles_Thrall.pl
|
||||
RULE_BOOL(Bots, QuestableSpells, false) // Anita Thrall's (Anita_Thrall.pl) Bot Spell Scriber quests.
|
||||
RULE_INT(Bots, SpawnLimit, 71) // Number of bots a character can have spawned at one time, You + 71 bots is a 12 group pseudo-raid (bots are not raidable at this time)
|
||||
RULE_INT(Bots, SpawnLimit, 71) // Number of bots a character can have spawned at one time, You + 71 bots is a 12 group raid
|
||||
RULE_BOOL(Bots, BotGroupXP, false) // Determines whether client gets xp for bots outside their group.
|
||||
RULE_BOOL(Bots, BotBardUseOutOfCombatSongs, true) // Determines whether bard bots use additional out of combat songs (optional script)
|
||||
RULE_BOOL(Bots, BotLevelsWithOwner, false) // Auto-updates spawned bots as owner levels/de-levels (false is original behavior)
|
||||
RULE_BOOL(Bots, BotCharacterLevelEnabled, false) // Enables required level to spawn bots
|
||||
RULE_INT(Bots, BotCharacterLevel, 0) // 0 as default (if level > this value you can spawn bots if BotCharacterLevelEnabled is true)
|
||||
RULE_INT(Bots, CasterStopMeleeLevel, 13) // Level at which caster bots stop melee attacks
|
||||
RULE_CATEGORY_END()
|
||||
#endif
|
||||
|
||||
|
||||
+4
-4
@@ -21,8 +21,8 @@
|
||||
#include "emu_constants.h"
|
||||
|
||||
#include "string_util.h"
|
||||
#include "item_instance.h"
|
||||
#include "item_data.h"
|
||||
#include "item.h"
|
||||
#include "item_base.h"
|
||||
#include "../zone/zonedb.h"
|
||||
|
||||
|
||||
@@ -147,7 +147,7 @@ void EQEmu::SayLinkEngine::generate_body()
|
||||
|
||||
memset(&m_LinkBodyStruct, 0, sizeof(SayLinkBody_Struct));
|
||||
|
||||
const EQEmu::ItemData* item_data = nullptr;
|
||||
const EQEmu::ItemBase* item_data = nullptr;
|
||||
|
||||
switch (m_LinkType) {
|
||||
case saylink::SayLinkBlank:
|
||||
@@ -250,7 +250,7 @@ void EQEmu::SayLinkEngine::generate_text()
|
||||
return;
|
||||
}
|
||||
|
||||
const EQEmu::ItemData* item_data = nullptr;
|
||||
const EQEmu::ItemBase* item_data = nullptr;
|
||||
|
||||
switch (m_LinkType) {
|
||||
case saylink::SayLinkBlank:
|
||||
|
||||
+6
-6
@@ -26,11 +26,11 @@
|
||||
|
||||
|
||||
struct ServerLootItem_Struct;
|
||||
class ItemInst;
|
||||
|
||||
namespace EQEmu
|
||||
{
|
||||
struct ItemData;
|
||||
class ItemInstance;
|
||||
struct ItemBase;
|
||||
struct SayLinkBody_Struct;
|
||||
|
||||
namespace saylink {
|
||||
@@ -67,9 +67,9 @@ namespace EQEmu
|
||||
SayLinkEngine();
|
||||
|
||||
void SetLinkType(saylink::SayLinkType link_type) { m_LinkType = link_type; }
|
||||
void SetItemData(const EQEmu::ItemData* item_data) { m_ItemData = item_data; }
|
||||
void SetItemData(const EQEmu::ItemBase* item_data) { m_ItemData = item_data; }
|
||||
void SetLootData(const ServerLootItem_Struct* loot_data) { m_LootData = loot_data; }
|
||||
void SetItemInst(const ItemInstance* item_inst) { m_ItemInst = item_inst; }
|
||||
void SetItemInst(const ItemInst* item_inst) { m_ItemInst = item_inst; }
|
||||
|
||||
// mainly for saylinks..but, not limited to
|
||||
void SetProxyUnknown1(uint8 proxy_unknown_1) { m_Proxy_unknown_1 = proxy_unknown_1; }
|
||||
@@ -103,9 +103,9 @@ namespace EQEmu
|
||||
void generate_text();
|
||||
|
||||
int m_LinkType;
|
||||
const ItemData* m_ItemData;
|
||||
const ItemBase* m_ItemData;
|
||||
const ServerLootItem_Struct* m_LootData;
|
||||
const ItemInstance* m_ItemInst;
|
||||
const ItemInst* m_ItemInst;
|
||||
|
||||
uint8 m_Proxy_unknown_1;
|
||||
uint32 m_ProxyItemID;
|
||||
|
||||
+7
-11
@@ -193,10 +193,15 @@
|
||||
#define ServerOP_QSSendQuery 0x5016
|
||||
#define ServerOP_CZSignalNPC 0x5017
|
||||
#define ServerOP_CZSetEntityVariableByNPCTypeID 0x5018
|
||||
#define ServerOP_WWMarquee 0x5019
|
||||
|
||||
#define ServerOP_WIRemoteCall 0x5001
|
||||
#define ServerOP_WIRemoteCallResponse 0x5002
|
||||
#define ServerOP_WIRemoteCallToClient 0x5003
|
||||
#define ServerOP_WIClientSession 0x5004
|
||||
#define ServerOP_WIClientSessionResponse 0x5005
|
||||
|
||||
/* Query Serv Generic Packet Flag/Type Enumeration */
|
||||
enum { QSG_LFGuild = 0 };
|
||||
enum { QSG_LFGuild = 0 };
|
||||
enum { QSG_LFGuild_PlayerMatches = 0, QSG_LFGuild_UpdatePlayerInfo, QSG_LFGuild_RequestPlayerInfo, QSG_LFGuild_UpdateGuildInfo, QSG_LFGuild_GuildMatches,
|
||||
QSG_LFGuild_RequestGuildInfo };
|
||||
|
||||
@@ -1255,15 +1260,6 @@ struct CZMessagePlayer_Struct {
|
||||
char Message[512];
|
||||
};
|
||||
|
||||
struct WWMarquee_Struct {
|
||||
uint32 Type;
|
||||
uint32 Priority;
|
||||
uint32 FadeIn;
|
||||
uint32 FadeOut;
|
||||
uint32 Duration;
|
||||
char Message[512];
|
||||
};
|
||||
|
||||
struct CZSetEntVarByNPCTypeID_Struct {
|
||||
uint32 npctype_id;
|
||||
char id[256];
|
||||
|
||||
+93
-81
@@ -29,7 +29,7 @@
|
||||
#include "faction.h"
|
||||
#include "features.h"
|
||||
#include "ipc_mutex.h"
|
||||
#include "inventory_profile.h"
|
||||
#include "item.h"
|
||||
#include "loottable.h"
|
||||
#include "memory_mapped_file.h"
|
||||
#include "mysql.h"
|
||||
@@ -38,17 +38,6 @@
|
||||
#include "string_util.h"
|
||||
#include "eqemu_config.h"
|
||||
|
||||
namespace ItemField
|
||||
{
|
||||
enum {
|
||||
source = 0,
|
||||
#define F(x) x,
|
||||
#include "item_fieldlist.h"
|
||||
#undef F
|
||||
updated
|
||||
};
|
||||
}
|
||||
|
||||
SharedDatabase::SharedDatabase()
|
||||
: Database()
|
||||
{
|
||||
@@ -110,13 +99,13 @@ uint32 SharedDatabase::GetTotalTimeEntitledOnAccount(uint32 AccountID) {
|
||||
return EntitledTime;
|
||||
}
|
||||
|
||||
bool SharedDatabase::SaveCursor(uint32 char_id, std::list<EQEmu::ItemInstance*>::const_iterator &start, std::list<EQEmu::ItemInstance*>::const_iterator &end)
|
||||
bool SharedDatabase::SaveCursor(uint32 char_id, std::list<ItemInst*>::const_iterator &start, std::list<ItemInst*>::const_iterator &end)
|
||||
{
|
||||
// Delete cursor items
|
||||
std::string query = StringFormat("DELETE FROM inventory WHERE charid = %i "
|
||||
"AND ((slotid >= 8000 AND slotid <= 8999) "
|
||||
"OR slotid = %i OR (slotid >= %i AND slotid <= %i) )",
|
||||
char_id, EQEmu::inventory::slotCursor,
|
||||
char_id, EQEmu::legacy::SlotCursor,
|
||||
EQEmu::legacy::CURSOR_BAG_BEGIN, EQEmu::legacy::CURSOR_BAG_END);
|
||||
auto results = QueryDatabase(query);
|
||||
if (!results.Success()) {
|
||||
@@ -127,8 +116,8 @@ bool SharedDatabase::SaveCursor(uint32 char_id, std::list<EQEmu::ItemInstance*>:
|
||||
int i = 8000;
|
||||
for(auto it = start; it != end; ++it, i++) {
|
||||
if (i > 8999) { break; } // shouldn't be anything in the queue that indexes this high
|
||||
EQEmu::ItemInstance *inst = *it;
|
||||
int16 use_slot = (i == 8000) ? EQEmu::inventory::slotCursor : i;
|
||||
ItemInst *inst = *it;
|
||||
int16 use_slot = (i == 8000) ? EQEmu::legacy::SlotCursor : i;
|
||||
if (!SaveInventory(char_id, inst, use_slot)) {
|
||||
return false;
|
||||
}
|
||||
@@ -137,7 +126,7 @@ bool SharedDatabase::SaveCursor(uint32 char_id, std::list<EQEmu::ItemInstance*>:
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SharedDatabase::VerifyInventory(uint32 account_id, int16 slot_id, const EQEmu::ItemInstance* inst)
|
||||
bool SharedDatabase::VerifyInventory(uint32 account_id, int16 slot_id, const ItemInst* inst)
|
||||
{
|
||||
// Delete cursor items
|
||||
std::string query = StringFormat("SELECT itemid, charges FROM sharedbank "
|
||||
@@ -170,7 +159,7 @@ bool SharedDatabase::VerifyInventory(uint32 account_id, int16 slot_id, const EQE
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SharedDatabase::SaveInventory(uint32 char_id, const EQEmu::ItemInstance* inst, int16 slot_id) {
|
||||
bool SharedDatabase::SaveInventory(uint32 char_id, const ItemInst* inst, int16 slot_id) {
|
||||
|
||||
//never save tribute slots:
|
||||
if (slot_id >= EQEmu::legacy::TRIBUTE_BEGIN && slot_id <= EQEmu::legacy::TRIBUTE_END)
|
||||
@@ -184,7 +173,7 @@ bool SharedDatabase::SaveInventory(uint32 char_id, const EQEmu::ItemInstance* in
|
||||
else {
|
||||
// Needed to clear out bag slots that 'REPLACE' in UpdateSharedBankSlot does not overwrite..otherwise, duplication occurs
|
||||
// (This requires that parent then child items be sent..which should be how they are currently passed)
|
||||
if (EQEmu::InventoryProfile::SupportsContainers(slot_id))
|
||||
if (Inventory::SupportsContainers(slot_id))
|
||||
DeleteSharedBankSlot(char_id, slot_id);
|
||||
return UpdateSharedBankSlot(char_id, inst, slot_id);
|
||||
}
|
||||
@@ -195,18 +184,18 @@ bool SharedDatabase::SaveInventory(uint32 char_id, const EQEmu::ItemInstance* in
|
||||
|
||||
// Needed to clear out bag slots that 'REPLACE' in UpdateInventorySlot does not overwrite..otherwise, duplication occurs
|
||||
// (This requires that parent then child items be sent..which should be how they are currently passed)
|
||||
if (EQEmu::InventoryProfile::SupportsContainers(slot_id))
|
||||
if (Inventory::SupportsContainers(slot_id))
|
||||
DeleteInventorySlot(char_id, slot_id);
|
||||
return UpdateInventorySlot(char_id, inst, slot_id);
|
||||
}
|
||||
|
||||
bool SharedDatabase::UpdateInventorySlot(uint32 char_id, const EQEmu::ItemInstance* inst, int16 slot_id) {
|
||||
bool SharedDatabase::UpdateInventorySlot(uint32 char_id, const ItemInst* inst, int16 slot_id) {
|
||||
// need to check 'inst' argument for valid pointer
|
||||
|
||||
uint32 augslot[EQEmu::inventory::SocketCount] = { 0, 0, 0, 0, 0, 0 };
|
||||
uint32 augslot[EQEmu::legacy::ITEM_COMMON_SIZE] = { 0, 0, 0, 0, 0, 0 };
|
||||
if (inst->IsClassCommon()) {
|
||||
for (int i = EQEmu::inventory::socketBegin; i < EQEmu::inventory::SocketCount; i++) {
|
||||
EQEmu::ItemInstance *auginst = inst->GetItem(i);
|
||||
for (int i = AUG_INDEX_BEGIN; i < EQEmu::legacy::ITEM_COMMON_SIZE; i++) {
|
||||
ItemInst *auginst = inst->GetItem(i);
|
||||
augslot[i] = (auginst && auginst->GetItem()) ? auginst->GetItem()->ID : 0;
|
||||
}
|
||||
}
|
||||
@@ -232,12 +221,12 @@ bool SharedDatabase::UpdateInventorySlot(uint32 char_id, const EQEmu::ItemInstan
|
||||
auto results = QueryDatabase(query);
|
||||
|
||||
// Save bag contents, if slot supports bag contents
|
||||
if (inst->IsClassBag() && EQEmu::InventoryProfile::SupportsContainers(slot_id))
|
||||
if (inst->IsClassBag() && Inventory::SupportsContainers(slot_id))
|
||||
// Limiting to bag slot count will get rid of 'hidden' duplicated items and 'Invalid Slot ID'
|
||||
// messages through attrition (and the modded code in SaveInventory)
|
||||
for (uint8 idx = EQEmu::inventory::containerBegin; idx < inst->GetItem()->BagSlots && idx < EQEmu::inventory::ContainerCount; idx++) {
|
||||
const EQEmu::ItemInstance* baginst = inst->GetItem(idx);
|
||||
SaveInventory(char_id, baginst, EQEmu::InventoryProfile::CalcSlotId(slot_id, idx));
|
||||
for (uint8 idx = SUB_INDEX_BEGIN; idx < inst->GetItem()->BagSlots && idx < EQEmu::legacy::ITEM_CONTAINER_SIZE; idx++) {
|
||||
const ItemInst* baginst = inst->GetItem(idx);
|
||||
SaveInventory(char_id, baginst, Inventory::CalcSlotId(slot_id, idx));
|
||||
}
|
||||
|
||||
if (!results.Success()) {
|
||||
@@ -247,13 +236,13 @@ bool SharedDatabase::UpdateInventorySlot(uint32 char_id, const EQEmu::ItemInstan
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SharedDatabase::UpdateSharedBankSlot(uint32 char_id, const EQEmu::ItemInstance* inst, int16 slot_id) {
|
||||
bool SharedDatabase::UpdateSharedBankSlot(uint32 char_id, const ItemInst* inst, int16 slot_id) {
|
||||
// need to check 'inst' argument for valid pointer
|
||||
|
||||
uint32 augslot[EQEmu::inventory::SocketCount] = { 0, 0, 0, 0, 0, 0 };
|
||||
uint32 augslot[EQEmu::legacy::ITEM_COMMON_SIZE] = { 0, 0, 0, 0, 0, 0 };
|
||||
if (inst->IsClassCommon()) {
|
||||
for (int i = EQEmu::inventory::socketBegin; i < EQEmu::inventory::SocketCount; i++) {
|
||||
EQEmu::ItemInstance *auginst = inst->GetItem(i);
|
||||
for (int i = AUG_INDEX_BEGIN; i < EQEmu::legacy::ITEM_COMMON_SIZE; i++) {
|
||||
ItemInst *auginst = inst->GetItem(i);
|
||||
augslot[i] = (auginst && auginst->GetItem()) ? auginst->GetItem()->ID : 0;
|
||||
}
|
||||
}
|
||||
@@ -278,12 +267,12 @@ bool SharedDatabase::UpdateSharedBankSlot(uint32 char_id, const EQEmu::ItemInsta
|
||||
auto results = QueryDatabase(query);
|
||||
|
||||
// Save bag contents, if slot supports bag contents
|
||||
if (inst->IsClassBag() && EQEmu::InventoryProfile::SupportsContainers(slot_id)) {
|
||||
if (inst->IsClassBag() && Inventory::SupportsContainers(slot_id)) {
|
||||
// Limiting to bag slot count will get rid of 'hidden' duplicated items and 'Invalid Slot ID'
|
||||
// messages through attrition (and the modded code in SaveInventory)
|
||||
for (uint8 idx = EQEmu::inventory::containerBegin; idx < inst->GetItem()->BagSlots && idx < EQEmu::inventory::ContainerCount; idx++) {
|
||||
const EQEmu::ItemInstance* baginst = inst->GetItem(idx);
|
||||
SaveInventory(char_id, baginst, EQEmu::InventoryProfile::CalcSlotId(slot_id, idx));
|
||||
for (uint8 idx = SUB_INDEX_BEGIN; idx < inst->GetItem()->BagSlots && idx < EQEmu::legacy::ITEM_CONTAINER_SIZE; idx++) {
|
||||
const ItemInst* baginst = inst->GetItem(idx);
|
||||
SaveInventory(char_id, baginst, Inventory::CalcSlotId(slot_id, idx));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -304,10 +293,10 @@ bool SharedDatabase::DeleteInventorySlot(uint32 char_id, int16 slot_id) {
|
||||
}
|
||||
|
||||
// Delete bag slots, if need be
|
||||
if (!EQEmu::InventoryProfile::SupportsContainers(slot_id))
|
||||
if (!Inventory::SupportsContainers(slot_id))
|
||||
return true;
|
||||
|
||||
int16 base_slot_id = EQEmu::InventoryProfile::CalcSlotId(slot_id, EQEmu::inventory::containerBegin);
|
||||
int16 base_slot_id = Inventory::CalcSlotId(slot_id, SUB_INDEX_BEGIN);
|
||||
query = StringFormat("DELETE FROM inventory WHERE charid = %i AND slotid >= %i AND slotid < %i",
|
||||
char_id, base_slot_id, (base_slot_id+10));
|
||||
results = QueryDatabase(query);
|
||||
@@ -330,10 +319,10 @@ bool SharedDatabase::DeleteSharedBankSlot(uint32 char_id, int16 slot_id) {
|
||||
}
|
||||
|
||||
// Delete bag slots, if need be
|
||||
if (!EQEmu::InventoryProfile::SupportsContainers(slot_id))
|
||||
if (!Inventory::SupportsContainers(slot_id))
|
||||
return true;
|
||||
|
||||
int16 base_slot_id = EQEmu::InventoryProfile::CalcSlotId(slot_id, EQEmu::inventory::containerBegin);
|
||||
int16 base_slot_id = Inventory::CalcSlotId(slot_id, SUB_INDEX_BEGIN);
|
||||
query = StringFormat("DELETE FROM sharedbank WHERE acctid = %i "
|
||||
"AND slotid >= %i AND slotid < %i",
|
||||
account_id, base_slot_id, (base_slot_id+10));
|
||||
@@ -373,9 +362,9 @@ bool SharedDatabase::SetSharedPlatinum(uint32 account_id, int32 amount_to_add) {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SharedDatabase::SetStartingItems(PlayerProfile_Struct* pp, EQEmu::InventoryProfile* inv, uint32 si_race, uint32 si_class, uint32 si_deity, uint32 si_current_zone, char* si_name, int admin_level) {
|
||||
bool SharedDatabase::SetStartingItems(PlayerProfile_Struct* pp, Inventory* inv, uint32 si_race, uint32 si_class, uint32 si_deity, uint32 si_current_zone, char* si_name, int admin_level) {
|
||||
|
||||
const EQEmu::ItemData* myitem;
|
||||
const EQEmu::ItemBase* myitem;
|
||||
|
||||
std::string query = StringFormat("SELECT itemid, item_charges, slot FROM starting_items "
|
||||
"WHERE (race = %i or race = 0) AND (class = %i or class = 0) AND "
|
||||
@@ -396,7 +385,7 @@ bool SharedDatabase::SetStartingItems(PlayerProfile_Struct* pp, EQEmu::Inventory
|
||||
if(!myitem)
|
||||
continue;
|
||||
|
||||
EQEmu::ItemInstance* myinst = CreateBaseItem(myitem, charges);
|
||||
ItemInst* myinst = CreateBaseItem(myitem, charges);
|
||||
|
||||
if(slot < 0)
|
||||
slot = inv->FindFreeSlot(0, 0);
|
||||
@@ -410,7 +399,7 @@ bool SharedDatabase::SetStartingItems(PlayerProfile_Struct* pp, EQEmu::Inventory
|
||||
|
||||
|
||||
// Retrieve shared bank inventory based on either account or character
|
||||
bool SharedDatabase::GetSharedBank(uint32 id, EQEmu::InventoryProfile *inv, bool is_charid)
|
||||
bool SharedDatabase::GetSharedBank(uint32 id, Inventory *inv, bool is_charid)
|
||||
{
|
||||
std::string query;
|
||||
|
||||
@@ -439,7 +428,7 @@ bool SharedDatabase::GetSharedBank(uint32 id, EQEmu::InventoryProfile *inv, bool
|
||||
uint32 item_id = (uint32)atoi(row[1]);
|
||||
int8 charges = (int8)atoi(row[2]);
|
||||
|
||||
uint32 aug[EQEmu::inventory::SocketCount];
|
||||
uint32 aug[EQEmu::legacy::ITEM_COMMON_SIZE];
|
||||
aug[0] = (uint32)atoi(row[3]);
|
||||
aug[1] = (uint32)atoi(row[4]);
|
||||
aug[2] = (uint32)atoi(row[5]);
|
||||
@@ -447,7 +436,7 @@ bool SharedDatabase::GetSharedBank(uint32 id, EQEmu::InventoryProfile *inv, bool
|
||||
aug[4] = (uint32)atoi(row[7]);
|
||||
aug[5] = (uint32)atoi(row[8]);
|
||||
|
||||
const EQEmu::ItemData *item = GetItem(item_id);
|
||||
const EQEmu::ItemBase *item = GetItem(item_id);
|
||||
|
||||
if (!item) {
|
||||
Log.Out(Logs::General, Logs::Error,
|
||||
@@ -458,9 +447,9 @@ bool SharedDatabase::GetSharedBank(uint32 id, EQEmu::InventoryProfile *inv, bool
|
||||
|
||||
int16 put_slot_id = INVALID_INDEX;
|
||||
|
||||
EQEmu::ItemInstance *inst = CreateBaseItem(item, charges);
|
||||
ItemInst *inst = CreateBaseItem(item, charges);
|
||||
if (inst && item->IsClassCommon()) {
|
||||
for (int i = EQEmu::inventory::socketBegin; i < EQEmu::inventory::SocketCount; i++) {
|
||||
for (int i = AUG_INDEX_BEGIN; i < EQEmu::legacy::ITEM_COMMON_SIZE; i++) {
|
||||
if (aug[i])
|
||||
inst->PutAugment(this, i, aug[i]);
|
||||
}
|
||||
@@ -511,7 +500,7 @@ bool SharedDatabase::GetSharedBank(uint32 id, EQEmu::InventoryProfile *inv, bool
|
||||
}
|
||||
|
||||
// Overloaded: Retrieve character inventory based on character id
|
||||
bool SharedDatabase::GetInventory(uint32 char_id, EQEmu::InventoryProfile *inv)
|
||||
bool SharedDatabase::GetInventory(uint32 char_id, Inventory *inv)
|
||||
{
|
||||
// Retrieve character inventory
|
||||
std::string query =
|
||||
@@ -535,7 +524,7 @@ bool SharedDatabase::GetInventory(uint32 char_id, EQEmu::InventoryProfile *inv)
|
||||
uint16 charges = atoi(row[2]);
|
||||
uint32 color = atoul(row[3]);
|
||||
|
||||
uint32 aug[EQEmu::inventory::SocketCount];
|
||||
uint32 aug[EQEmu::legacy::ITEM_COMMON_SIZE];
|
||||
|
||||
aug[0] = (uint32)atoul(row[4]);
|
||||
aug[1] = (uint32)atoul(row[5]);
|
||||
@@ -550,7 +539,7 @@ bool SharedDatabase::GetInventory(uint32 char_id, EQEmu::InventoryProfile *inv)
|
||||
uint32 ornament_idfile = (uint32)atoul(row[13]);
|
||||
uint32 ornament_hero_model = (uint32)atoul(row[14]);
|
||||
|
||||
const EQEmu::ItemData *item = GetItem(item_id);
|
||||
const EQEmu::ItemBase *item = GetItem(item_id);
|
||||
|
||||
if (!item) {
|
||||
Log.Out(Logs::General, Logs::Error,
|
||||
@@ -561,7 +550,7 @@ bool SharedDatabase::GetInventory(uint32 char_id, EQEmu::InventoryProfile *inv)
|
||||
|
||||
int16 put_slot_id = INVALID_INDEX;
|
||||
|
||||
EQEmu::ItemInstance *inst = CreateBaseItem(item, charges);
|
||||
ItemInst *inst = CreateBaseItem(item, charges);
|
||||
|
||||
if (inst == nullptr)
|
||||
continue;
|
||||
@@ -594,11 +583,11 @@ bool SharedDatabase::GetInventory(uint32 char_id, EQEmu::InventoryProfile *inv)
|
||||
|
||||
inst->SetOrnamentIcon(ornament_icon);
|
||||
inst->SetOrnamentationIDFile(ornament_idfile);
|
||||
inst->SetOrnamentHeroModel(item->HerosForgeModel);
|
||||
inst->SetOrnamentHeroModel(ornament_hero_model);
|
||||
|
||||
if (instnodrop ||
|
||||
(((slot_id >= EQEmu::legacy::EQUIPMENT_BEGIN && slot_id <= EQEmu::legacy::EQUIPMENT_END) ||
|
||||
slot_id == EQEmu::inventory::slotPowerSource) &&
|
||||
slot_id == EQEmu::legacy::SlotPowerSource) &&
|
||||
inst->GetItem()->Attuneable))
|
||||
inst->SetAttuned(true);
|
||||
|
||||
@@ -620,7 +609,7 @@ bool SharedDatabase::GetInventory(uint32 char_id, EQEmu::InventoryProfile *inv)
|
||||
}
|
||||
|
||||
if (item->IsClassCommon()) {
|
||||
for (int i = EQEmu::inventory::socketBegin; i < EQEmu::inventory::SocketCount; i++) {
|
||||
for (int i = AUG_INDEX_BEGIN; i < EQEmu::legacy::ITEM_COMMON_SIZE; i++) {
|
||||
if (aug[i])
|
||||
inst->PutAugment(this, i, aug[i]);
|
||||
}
|
||||
@@ -653,7 +642,7 @@ bool SharedDatabase::GetInventory(uint32 char_id, EQEmu::InventoryProfile *inv)
|
||||
}
|
||||
|
||||
// Overloaded: Retrieve character inventory based on account_id and character name
|
||||
bool SharedDatabase::GetInventory(uint32 account_id, char *name, EQEmu::InventoryProfile *inv)
|
||||
bool SharedDatabase::GetInventory(uint32 account_id, char *name, Inventory *inv)
|
||||
{
|
||||
// Retrieve character inventory
|
||||
std::string query =
|
||||
@@ -677,7 +666,7 @@ bool SharedDatabase::GetInventory(uint32 account_id, char *name, EQEmu::Inventor
|
||||
int8 charges = atoi(row[2]);
|
||||
uint32 color = atoul(row[3]);
|
||||
|
||||
uint32 aug[EQEmu::inventory::SocketCount];
|
||||
uint32 aug[EQEmu::legacy::ITEM_COMMON_SIZE];
|
||||
aug[0] = (uint32)atoi(row[4]);
|
||||
aug[1] = (uint32)atoi(row[5]);
|
||||
aug[2] = (uint32)atoi(row[6]);
|
||||
@@ -690,12 +679,12 @@ bool SharedDatabase::GetInventory(uint32 account_id, char *name, EQEmu::Inventor
|
||||
uint32 ornament_idfile = (uint32)atoul(row[13]);
|
||||
uint32 ornament_hero_model = (uint32)atoul(row[14]);
|
||||
|
||||
const EQEmu::ItemData *item = GetItem(item_id);
|
||||
const EQEmu::ItemBase *item = GetItem(item_id);
|
||||
int16 put_slot_id = INVALID_INDEX;
|
||||
if (!item)
|
||||
continue;
|
||||
|
||||
EQEmu::ItemInstance *inst = CreateBaseItem(item, charges);
|
||||
ItemInst *inst = CreateBaseItem(item, charges);
|
||||
|
||||
if (inst == nullptr)
|
||||
continue;
|
||||
@@ -730,7 +719,7 @@ bool SharedDatabase::GetInventory(uint32 account_id, char *name, EQEmu::Inventor
|
||||
|
||||
inst->SetOrnamentIcon(ornament_icon);
|
||||
inst->SetOrnamentationIDFile(ornament_idfile);
|
||||
inst->SetOrnamentHeroModel(item->HerosForgeModel);
|
||||
inst->SetOrnamentHeroModel(ornament_hero_model);
|
||||
|
||||
if (color > 0)
|
||||
inst->SetColor(color);
|
||||
@@ -738,7 +727,7 @@ bool SharedDatabase::GetInventory(uint32 account_id, char *name, EQEmu::Inventor
|
||||
inst->SetCharges(charges);
|
||||
|
||||
if (item->IsClassCommon()) {
|
||||
for (int i = EQEmu::inventory::socketBegin; i < EQEmu::inventory::SocketCount; i++) {
|
||||
for (int i = AUG_INDEX_BEGIN; i < EQEmu::legacy::ITEM_COMMON_SIZE; i++) {
|
||||
if (aug[i])
|
||||
inst->PutAugment(this, i, aug[i]);
|
||||
}
|
||||
@@ -827,7 +816,7 @@ bool SharedDatabase::LoadItems(const std::string &prefix) {
|
||||
mutex.Lock();
|
||||
std::string file_name = Config->SharedMemDir + prefix + std::string("items");
|
||||
items_mmf = std::unique_ptr<EQEmu::MemoryMappedFile>(new EQEmu::MemoryMappedFile(file_name));
|
||||
items_hash = std::unique_ptr<EQEmu::FixedMemoryHashSet<EQEmu::ItemData>>(new EQEmu::FixedMemoryHashSet<EQEmu::ItemData>(reinterpret_cast<uint8*>(items_mmf->Get()), items_mmf->Size()));
|
||||
items_hash = std::unique_ptr<EQEmu::FixedMemoryHashSet<EQEmu::ItemBase>>(new EQEmu::FixedMemoryHashSet<EQEmu::ItemBase>(reinterpret_cast<uint8*>(items_mmf->Get()), items_mmf->Size()));
|
||||
mutex.Unlock();
|
||||
} catch(std::exception& ex) {
|
||||
Log.Out(Logs::General, Logs::Error, "Error Loading Items: %s", ex.what());
|
||||
@@ -839,7 +828,7 @@ bool SharedDatabase::LoadItems(const std::string &prefix) {
|
||||
|
||||
void SharedDatabase::LoadItems(void *data, uint32 size, int32 items, uint32 max_item_id)
|
||||
{
|
||||
EQEmu::FixedMemoryHashSet<EQEmu::ItemData> hash(reinterpret_cast<uint8 *>(data), size, items, max_item_id);
|
||||
EQEmu::FixedMemoryHashSet<EQEmu::ItemBase> hash(reinterpret_cast<uint8 *>(data), size, items, max_item_id);
|
||||
|
||||
std::string ndbuffer;
|
||||
bool disableNoRent = false;
|
||||
@@ -867,7 +856,7 @@ void SharedDatabase::LoadItems(void *data, uint32 size, int32 items, uint32 max_
|
||||
}
|
||||
}
|
||||
|
||||
EQEmu::ItemData item;
|
||||
EQEmu::ItemBase item;
|
||||
|
||||
const std::string query = "SELECT source,"
|
||||
#define F(x) "`"#x"`,"
|
||||
@@ -880,7 +869,7 @@ void SharedDatabase::LoadItems(void *data, uint32 size, int32 items, uint32 max_
|
||||
}
|
||||
|
||||
for (auto row = results.begin(); row != results.end(); ++row) {
|
||||
memset(&item, 0, sizeof(EQEmu::ItemData));
|
||||
memset(&item, 0, sizeof(EQEmu::ItemBase));
|
||||
|
||||
item.ItemClass = (uint8)atoi(row[ItemField::itemclass]);
|
||||
strcpy(item.Name, row[ItemField::name]);
|
||||
@@ -1097,7 +1086,7 @@ void SharedDatabase::LoadItems(void *data, uint32 size, int32 items, uint32 max_
|
||||
}
|
||||
}
|
||||
|
||||
const EQEmu::ItemData* SharedDatabase::GetItem(uint32 id) {
|
||||
const EQEmu::ItemBase* SharedDatabase::GetItem(uint32 id) {
|
||||
if (id == 0)
|
||||
{
|
||||
return nullptr;
|
||||
@@ -1116,7 +1105,7 @@ const EQEmu::ItemData* SharedDatabase::GetItem(uint32 id) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
const EQEmu::ItemData* SharedDatabase::IterateItems(uint32* id) {
|
||||
const EQEmu::ItemBase* SharedDatabase::IterateItems(uint32* id) {
|
||||
if(!items_hash || !id) {
|
||||
return nullptr;
|
||||
}
|
||||
@@ -1261,18 +1250,18 @@ bool SharedDatabase::LoadNPCFactionLists(const std::string &prefix) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Create appropriate EQEmu::ItemInstance class
|
||||
EQEmu::ItemInstance* SharedDatabase::CreateItem(uint32 item_id, int16 charges, uint32 aug1, uint32 aug2, uint32 aug3, uint32 aug4, uint32 aug5, uint32 aug6, uint8 attuned)
|
||||
// Create appropriate ItemInst class
|
||||
ItemInst* SharedDatabase::CreateItem(uint32 item_id, int16 charges, uint32 aug1, uint32 aug2, uint32 aug3, uint32 aug4, uint32 aug5, uint32 aug6, uint8 attuned)
|
||||
{
|
||||
const EQEmu::ItemData* item = nullptr;
|
||||
EQEmu::ItemInstance* inst = nullptr;
|
||||
const EQEmu::ItemBase* item = nullptr;
|
||||
ItemInst* inst = nullptr;
|
||||
|
||||
item = GetItem(item_id);
|
||||
if (item) {
|
||||
inst = CreateBaseItem(item, charges);
|
||||
|
||||
if (inst == nullptr) {
|
||||
Log.Out(Logs::General, Logs::Error, "Error: valid item data returned a null reference for EQEmu::ItemInstance creation in SharedDatabase::CreateItem()");
|
||||
Log.Out(Logs::General, Logs::Error, "Error: valid item data returned a null reference for ItemInst creation in SharedDatabase::CreateItem()");
|
||||
Log.Out(Logs::General, Logs::Error, "Item Data = ID: %u, Name: %s, Charges: %i", item->ID, item->Name, charges);
|
||||
return nullptr;
|
||||
}
|
||||
@@ -1290,15 +1279,15 @@ EQEmu::ItemInstance* SharedDatabase::CreateItem(uint32 item_id, int16 charges, u
|
||||
}
|
||||
|
||||
|
||||
// Create appropriate EQEmu::ItemInstance class
|
||||
EQEmu::ItemInstance* SharedDatabase::CreateItem(const EQEmu::ItemData* item, int16 charges, uint32 aug1, uint32 aug2, uint32 aug3, uint32 aug4, uint32 aug5, uint32 aug6, uint8 attuned)
|
||||
// Create appropriate ItemInst class
|
||||
ItemInst* SharedDatabase::CreateItem(const EQEmu::ItemBase* item, int16 charges, uint32 aug1, uint32 aug2, uint32 aug3, uint32 aug4, uint32 aug5, uint32 aug6, uint8 attuned)
|
||||
{
|
||||
EQEmu::ItemInstance* inst = nullptr;
|
||||
ItemInst* inst = nullptr;
|
||||
if (item) {
|
||||
inst = CreateBaseItem(item, charges);
|
||||
|
||||
if (inst == nullptr) {
|
||||
Log.Out(Logs::General, Logs::Error, "Error: valid item data returned a null reference for EQEmu::ItemInstance creation in SharedDatabase::CreateItem()");
|
||||
Log.Out(Logs::General, Logs::Error, "Error: valid item data returned a null reference for ItemInst creation in SharedDatabase::CreateItem()");
|
||||
Log.Out(Logs::General, Logs::Error, "Item Data = ID: %u, Name: %s, Charges: %i", item->ID, item->Name, charges);
|
||||
return nullptr;
|
||||
}
|
||||
@@ -1315,8 +1304,8 @@ EQEmu::ItemInstance* SharedDatabase::CreateItem(const EQEmu::ItemData* item, int
|
||||
return inst;
|
||||
}
|
||||
|
||||
EQEmu::ItemInstance* SharedDatabase::CreateBaseItem(const EQEmu::ItemData* item, int16 charges) {
|
||||
EQEmu::ItemInstance* inst = nullptr;
|
||||
ItemInst* SharedDatabase::CreateBaseItem(const EQEmu::ItemBase* item, int16 charges) {
|
||||
ItemInst* inst = nullptr;
|
||||
if (item) {
|
||||
// if maxcharges is -1 that means it is an unlimited use item.
|
||||
// set it to 1 charge so that it is usable on creation
|
||||
@@ -1326,10 +1315,10 @@ EQEmu::ItemInstance* SharedDatabase::CreateBaseItem(const EQEmu::ItemData* item,
|
||||
if(charges <= 0 && item->Stackable)
|
||||
charges = 1;
|
||||
|
||||
inst = new EQEmu::ItemInstance(item, charges);
|
||||
inst = new ItemInst(item, charges);
|
||||
|
||||
if (inst == nullptr) {
|
||||
Log.Out(Logs::General, Logs::Error, "Error: valid item data returned a null reference for EQEmu::ItemInstance creation in SharedDatabase::CreateBaseItem()");
|
||||
Log.Out(Logs::General, Logs::Error, "Error: valid item data returned a null reference for ItemInst creation in SharedDatabase::CreateBaseItem()");
|
||||
Log.Out(Logs::General, Logs::Error, "Item Data = ID: %u, Name: %s, Charges: %i", item->ID, item->Name, charges);
|
||||
return nullptr;
|
||||
}
|
||||
@@ -1700,7 +1689,6 @@ void SharedDatabase::LoadSpells(void *data, int max_spells) {
|
||||
sp[tempid].pvpresistcalc=atoi(row[178]);
|
||||
sp[tempid].pvpresistcap=atoi(row[179]);
|
||||
sp[tempid].spell_category=atoi(row[180]);
|
||||
sp[tempid].pcnpc_only_flag=atoi(row[183]);
|
||||
sp[tempid].cast_not_standing = atoi(row[184]) != 0;
|
||||
sp[tempid].can_mgb=atoi(row[185]);
|
||||
sp[tempid].dispel_flag = atoi(row[186]);
|
||||
@@ -2064,3 +2052,27 @@ void SharedDatabase::SaveCharacterInspectMessage(uint32 character_id, const Insp
|
||||
std::string query = StringFormat("REPLACE INTO `character_inspect_messages` (id, inspect_message) VALUES (%u, '%s')", character_id, EscapeString(message->text).c_str());
|
||||
auto results = QueryDatabase(query);
|
||||
}
|
||||
|
||||
bool SharedDatabase::VerifyToken(std::string token, int& status) {
|
||||
status = 0;
|
||||
if (token.length() > 64) {
|
||||
token = token.substr(0, 64);
|
||||
}
|
||||
|
||||
token = EscapeString(token);
|
||||
std::string query = StringFormat("SELECT status FROM tokens WHERE token='%s'", token.c_str());
|
||||
auto results = QueryDatabase(query);
|
||||
if (!results.Success())
|
||||
{
|
||||
std::cerr << "Error in SharedDatabase::VerifyToken query '" << query << "' " << results.ErrorMessage() << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (results.RowCount() != 1) {
|
||||
return false;
|
||||
}
|
||||
|
||||
auto row = results.begin();
|
||||
status = atoi(row[0]);
|
||||
return true;
|
||||
}
|
||||
|
||||
+22
-19
@@ -33,6 +33,8 @@
|
||||
#include <memory>
|
||||
|
||||
class EvolveInfo;
|
||||
class Inventory;
|
||||
class ItemInst;
|
||||
struct BaseDataStruct;
|
||||
struct InspectMessage_Struct;
|
||||
struct PlayerProfile_Struct;
|
||||
@@ -43,9 +45,7 @@ struct LootDrop_Struct;
|
||||
|
||||
namespace EQEmu
|
||||
{
|
||||
struct ItemData;
|
||||
class ItemInstance;
|
||||
class InventoryProfile;
|
||||
struct ItemBase;
|
||||
class MemoryMappedFile;
|
||||
}
|
||||
|
||||
@@ -74,24 +74,24 @@ class SharedDatabase : public Database
|
||||
uint32 GetTotalTimeEntitledOnAccount(uint32 AccountID);
|
||||
|
||||
/*
|
||||
Character InventoryProfile
|
||||
Character Inventory
|
||||
*/
|
||||
bool SaveCursor(uint32 char_id, std::list<EQEmu::ItemInstance*>::const_iterator &start, std::list<EQEmu::ItemInstance*>::const_iterator &end);
|
||||
bool SaveInventory(uint32 char_id, const EQEmu::ItemInstance* inst, int16 slot_id);
|
||||
bool SaveCursor(uint32 char_id, std::list<ItemInst*>::const_iterator &start, std::list<ItemInst*>::const_iterator &end);
|
||||
bool SaveInventory(uint32 char_id, const ItemInst* inst, int16 slot_id);
|
||||
bool DeleteSharedBankSlot(uint32 char_id, int16 slot_id);
|
||||
bool DeleteInventorySlot(uint32 char_id, int16 slot_id);
|
||||
bool UpdateInventorySlot(uint32 char_id, const EQEmu::ItemInstance* inst, int16 slot_id);
|
||||
bool UpdateSharedBankSlot(uint32 char_id, const EQEmu::ItemInstance* inst, int16 slot_id);
|
||||
bool VerifyInventory(uint32 account_id, int16 slot_id, const EQEmu::ItemInstance* inst);
|
||||
bool GetSharedBank(uint32 id, EQEmu::InventoryProfile* inv, bool is_charid);
|
||||
bool UpdateInventorySlot(uint32 char_id, const ItemInst* inst, int16 slot_id);
|
||||
bool UpdateSharedBankSlot(uint32 char_id, const ItemInst* inst, int16 slot_id);
|
||||
bool VerifyInventory(uint32 account_id, int16 slot_id, const ItemInst* inst);
|
||||
bool GetSharedBank(uint32 id, Inventory* inv, bool is_charid);
|
||||
int32 GetSharedPlatinum(uint32 account_id);
|
||||
bool SetSharedPlatinum(uint32 account_id, int32 amount_to_add);
|
||||
bool GetInventory(uint32 char_id, EQEmu::InventoryProfile* inv);
|
||||
bool GetInventory(uint32 account_id, char* name, EQEmu::InventoryProfile* inv);
|
||||
bool GetInventory(uint32 char_id, Inventory* inv);
|
||||
bool GetInventory(uint32 account_id, char* name, Inventory* inv);
|
||||
std::map<uint32, uint32> GetItemRecastTimestamps(uint32 char_id);
|
||||
uint32 GetItemRecastTimestamp(uint32 char_id, uint32 recast_type);
|
||||
void ClearOldRecastTimestamps(uint32 char_id);
|
||||
bool SetStartingItems(PlayerProfile_Struct* pp, EQEmu::InventoryProfile* inv, uint32 si_race, uint32 si_class, uint32 si_deity, uint32 si_current_zone, char* si_name, int admin);
|
||||
bool SetStartingItems(PlayerProfile_Struct* pp, Inventory* inv, uint32 si_race, uint32 si_class, uint32 si_deity, uint32 si_current_zone, char* si_name, int admin);
|
||||
|
||||
|
||||
std::string GetBook(const char *txtfile);
|
||||
@@ -99,9 +99,12 @@ class SharedDatabase : public Database
|
||||
/*
|
||||
Item Methods
|
||||
*/
|
||||
EQEmu::ItemInstance* CreateItem(uint32 item_id, int16 charges = 0, uint32 aug1 = 0, uint32 aug2 = 0, uint32 aug3 = 0, uint32 aug4 = 0, uint32 aug5 = 0, uint32 aug6 = 0, uint8 attuned = 0);
|
||||
EQEmu::ItemInstance* CreateItem(const EQEmu::ItemData* item, int16 charges = 0, uint32 aug1 = 0, uint32 aug2 = 0, uint32 aug3 = 0, uint32 aug4 = 0, uint32 aug5 = 0, uint32 aug6 = 0, uint8 attuned = 0);
|
||||
EQEmu::ItemInstance* CreateBaseItem(const EQEmu::ItemData* item, int16 charges = 0);
|
||||
ItemInst* CreateItem(uint32 item_id, int16 charges = 0, uint32 aug1 = 0, uint32 aug2 = 0, uint32 aug3 = 0, uint32 aug4 = 0, uint32 aug5 = 0, uint32 aug6 = 0, uint8 attuned = 0);
|
||||
ItemInst* CreateItem(const EQEmu::ItemBase* item, int16 charges = 0, uint32 aug1 = 0, uint32 aug2 = 0, uint32 aug3 = 0, uint32 aug4 = 0, uint32 aug5 = 0, uint32 aug6 = 0, uint8 attuned = 0);
|
||||
ItemInst* CreateBaseItem(const EQEmu::ItemBase* item, int16 charges = 0);
|
||||
|
||||
// Web Token Verification
|
||||
bool VerifyToken(std::string token, int& status);
|
||||
|
||||
/*
|
||||
Shared Memory crap
|
||||
@@ -111,8 +114,8 @@ class SharedDatabase : public Database
|
||||
void GetItemsCount(int32 &item_count, uint32 &max_id);
|
||||
void LoadItems(void *data, uint32 size, int32 items, uint32 max_item_id);
|
||||
bool LoadItems(const std::string &prefix);
|
||||
const EQEmu::ItemData* IterateItems(uint32* id);
|
||||
const EQEmu::ItemData* GetItem(uint32 id);
|
||||
const EQEmu::ItemBase* IterateItems(uint32* id);
|
||||
const EQEmu::ItemBase* GetItem(uint32 id);
|
||||
const EvolveInfo* GetEvolveInfo(uint32 loregroup);
|
||||
|
||||
//faction lists
|
||||
@@ -149,7 +152,7 @@ class SharedDatabase : public Database
|
||||
|
||||
std::unique_ptr<EQEmu::MemoryMappedFile> skill_caps_mmf;
|
||||
std::unique_ptr<EQEmu::MemoryMappedFile> items_mmf;
|
||||
std::unique_ptr<EQEmu::FixedMemoryHashSet<EQEmu::ItemData>> items_hash;
|
||||
std::unique_ptr<EQEmu::FixedMemoryHashSet<EQEmu::ItemBase>> items_hash;
|
||||
std::unique_ptr<EQEmu::MemoryMappedFile> faction_mmf;
|
||||
std::unique_ptr<EQEmu::FixedMemoryHashSet<NPCFactionList>> faction_hash;
|
||||
std::unique_ptr<EQEmu::MemoryMappedFile> loot_table_mmf;
|
||||
|
||||
@@ -124,30 +124,6 @@ bool EQEmu::skills::IsCastingSkill(SkillType skill)
|
||||
}
|
||||
}
|
||||
|
||||
int32 EQEmu::skills::GetBaseDamage(SkillType skill)
|
||||
{
|
||||
switch (skill) {
|
||||
case SkillBash:
|
||||
return 2;
|
||||
case SkillDragonPunch:
|
||||
return 12;
|
||||
case SkillEagleStrike:
|
||||
return 7;
|
||||
case SkillFlyingKick:
|
||||
return 25;
|
||||
case SkillKick:
|
||||
return 3;
|
||||
case SkillRoundKick:
|
||||
return 5;
|
||||
case SkillTigerClaw:
|
||||
return 4;
|
||||
case SkillFrenzy:
|
||||
return 10;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
const std::map<EQEmu::skills::SkillType, std::string>& EQEmu::skills::GetSkillTypeMap()
|
||||
{
|
||||
/* VS2013 code
|
||||
|
||||
@@ -166,7 +166,6 @@ namespace EQEmu
|
||||
float GetSkillMeleePushForce(SkillType skill);
|
||||
bool IsBardInstrumentSkill(SkillType skill);
|
||||
bool IsCastingSkill(SkillType skill);
|
||||
int32 GetBaseDamage(SkillType skill);
|
||||
|
||||
extern const std::map<SkillType, std::string>& GetSkillTypeMap();
|
||||
|
||||
|
||||
+2
-13
@@ -409,19 +409,8 @@ bool IsPartialCapableSpell(uint16 spell_id)
|
||||
if (spells[spell_id].no_partial_resist)
|
||||
return false;
|
||||
|
||||
// spell uses 600 (partial) scale if first effect is damage, else it uses 200 scale.
|
||||
// this includes DoTs. no_partial_resist excludes spells like necro snares
|
||||
for (int o = 0; o < EFFECT_COUNT; o++) {
|
||||
auto tid = spells[spell_id].effectid[o];
|
||||
|
||||
if (IsBlankSpellEffect(spell_id, o))
|
||||
continue;
|
||||
|
||||
if ((tid == SE_CurrentHPOnce || tid == SE_CurrentHP) && spells[spell_id].base[o] < 0)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
if (IsPureNukeSpell(spell_id))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
+4
-4
@@ -485,7 +485,7 @@ typedef enum {
|
||||
#define SE_ManaAbsorbPercentDamage 329 // implemented
|
||||
#define SE_CriticalDamageMob 330 // implemented
|
||||
#define SE_Salvage 331 // implemented - chance to recover items that would be destroyed in failed tradeskill combine
|
||||
#define SE_SummonToCorpse 332 // *not implemented AA - Call of the Wild (Druid/Shaman Res spell with no exp)
|
||||
//#define SE_SummonToCorpse 332 // *not implemented AA - Call of the Wild (Druid/Shaman Res spell with no exp)
|
||||
#define SE_CastOnRuneFadeEffect 333 // implemented
|
||||
#define SE_BardAEDot 334 // implemented
|
||||
#define SE_BlockNextSpellFocus 335 // implemented - base1 chance to block next spell ie Puratus (8494)
|
||||
@@ -502,7 +502,7 @@ typedef enum {
|
||||
#define SE_HeadShotLevel 346 // implemented[AA] - HeadShot max level to kill
|
||||
#define SE_DoubleRangedAttack 347 // implemented - chance at an additional archery attack (consumes arrow)
|
||||
#define SE_LimitManaMin 348 // implemented
|
||||
#define SE_ShieldEquipDmgMod 349 // implemented[AA] Increase melee base damage (indirectly increasing hate) when wearing a shield.
|
||||
#define SE_ShieldEquipHateMod 349 // implemented[AA] Increase melee hate when wearing a shield.
|
||||
#define SE_ManaBurn 350 // implemented - Drains mana for damage/heal at a defined ratio up to a defined maximum amount of mana.
|
||||
//#define SE_PersistentEffect 351 // *not implemented. creates a trap/totem that casts a spell (spell id + base1?) when anything comes near it. can probably make a beacon for this
|
||||
//#define SE_IncreaseTrapCount 352 // *not implemented - looks to be some type of invulnerability? Test ITC (8755)
|
||||
@@ -519,7 +519,7 @@ typedef enum {
|
||||
#define SE_BandolierSlots 363 // *not implemented[AA] 'Battle Ready' expands the bandolier by one additional save slot per rank.
|
||||
#define SE_TripleAttackChance 364 // implemented
|
||||
#define SE_ProcOnSpellKillShot 365 // implemented - chance to trigger a spell on kill when the kill is caused by a specific spell with this effect in it (10470 Venin)
|
||||
#define SE_GroupShielding 366 // *not implemented[AA] This gives you /shieldgroup
|
||||
#define SE_ShieldEquipDmgMod 366 // implemented[AA] Damage modifier to melee if shield equiped. (base1 = dmg mod , base2 = ?) ie Shield Specialist AA
|
||||
#define SE_SetBodyType 367 // implemented - set body type of base1 so it can be affected by spells that are limited to that type (Plant, Animal, Undead, etc)
|
||||
//#define SE_FactionMod 368 // *not implemented - increases faction with base1 (faction id, live won't match up w/ ours) by base2
|
||||
#define SE_CorruptionCounter 369 // implemented
|
||||
@@ -735,7 +735,7 @@ struct SPDat_Spell_Struct
|
||||
/* 180 */ int spell_category; // -- GLOBAL_GROUP
|
||||
/* 181 */ //int pvp_duration; // buffdurationformula for PvP -- PVP_DURATION
|
||||
/* 182 */ //int pvp_duration_cap; // buffduration for PvP -- PVP_DURATION_CAP
|
||||
/* 183 */ int pcnpc_only_flag; // valid values are 0, 1 = PCs (and mercs), and 2 = NPCs (and not mercs) -- PCNPC_ONLY_FLAG
|
||||
/* 183 */ //int pcnpc_only_flag; // valid values are 0, 1 = PCs (and mercs), and 2 = NPCs (and not mercs) -- PCNPC_ONLY_FLAG
|
||||
/* 184 */ bool cast_not_standing; // this is checked in the client's EQ_Spell::IsCastWhileInvisSpell, this also blocks SE_InterruptCasting from affecting this spell -- CAST_NOT_STANDING
|
||||
/* 185 */ bool can_mgb; // 0=no, -1 or 1 = yes -- CAN_MGB
|
||||
/* 186 */ int dispel_flag; // -- NO_DISPELL
|
||||
|
||||
@@ -18,3 +18,82 @@
|
||||
*/
|
||||
|
||||
#include "textures.h"
|
||||
//#include "inventory_slot.h"
|
||||
|
||||
#include <string.h> // temp
|
||||
|
||||
|
||||
//int EQEmu::textures::ConvertEquipmentSlotToTextureSlot(int equipment_slot)
|
||||
//{
|
||||
// switch (equipment_slot) {
|
||||
// case inventory::PossessionsHead:
|
||||
// return textures::TextureHead;
|
||||
// case inventory::PossessionsChest:
|
||||
// return textures::TextureChest;
|
||||
// case inventory::PossessionsArms:
|
||||
// return textures::TextureArms;
|
||||
// case inventory::PossessionsWrist1:
|
||||
// return textures::TextureWrist;
|
||||
// case inventory::PossessionsHands:
|
||||
// return textures::TextureHands;
|
||||
// case inventory::PossessionsLegs:
|
||||
// return textures::TextureLegs;
|
||||
// case inventory::PossessionsFeet:
|
||||
// return textures::TextureFeet;
|
||||
// case inventory::PossessionsPrimary:
|
||||
// return textures::TexturePrimary;
|
||||
// case inventory::PossessionsSecondary:
|
||||
// return textures::TextureSecondary;
|
||||
// default:
|
||||
// return textures::TextureInvalid;
|
||||
// }
|
||||
//}
|
||||
|
||||
//int EQEmu::textures::ConvertEquipmentSlotToTextureSlot(const InventorySlot &equipment_slot)
|
||||
//{
|
||||
// if (equipment_slot.Type() != inventory::InvTypePossessions || equipment_slot.Bag() != inventory::InvBagInvalid || equipment_slot.Aug() != inventory::InvAugInvalid)
|
||||
// return textures::TextureInvalid;
|
||||
//
|
||||
// return ConvertEquipmentSlotToTextureSlot(equipment_slot.Slot());
|
||||
//}
|
||||
|
||||
//EQEmu::InventorySlot EQEmu::textures::ConvertTextureSlotToEquipmentSlot(int texture_slot)
|
||||
//{
|
||||
// switch (texture_slot) {
|
||||
// case textures::TextureHead:
|
||||
// return EQEmu::InventorySlot(inventory::InvTypePossessions, inventory::PossessionsHead);
|
||||
// case textures::TextureChest:
|
||||
// return EQEmu::InventorySlot(inventory::InvTypePossessions, inventory::PossessionsChest);
|
||||
// case textures::TextureArms:
|
||||
// return EQEmu::InventorySlot(inventory::InvTypePossessions, inventory::PossessionsArms);
|
||||
// case textures::TextureWrist:
|
||||
// return EQEmu::InventorySlot(inventory::InvTypePossessions, inventory::PossessionsWrist1);
|
||||
// case textures::TextureHands:
|
||||
// return EQEmu::InventorySlot(inventory::InvTypePossessions, inventory::PossessionsHands);
|
||||
// case textures::TextureLegs:
|
||||
// return EQEmu::InventorySlot(inventory::InvTypePossessions, inventory::PossessionsLegs);
|
||||
// case textures::TextureFeet:
|
||||
// return EQEmu::InventorySlot(inventory::InvTypePossessions, inventory::PossessionsFeet);
|
||||
// case textures::TexturePrimary:
|
||||
// return EQEmu::InventorySlot(inventory::InvTypePossessions, inventory::PossessionsPrimary);
|
||||
// case textures::TextureSecondary:
|
||||
// return EQEmu::InventorySlot(inventory::InvTypePossessions, inventory::PossessionsSecondary);
|
||||
// default:
|
||||
// return EQEmu::InventorySlot();
|
||||
// }
|
||||
//}
|
||||
|
||||
EQEmu::TextureProfile::TextureProfile()
|
||||
{
|
||||
memset(&Slot, 0, (sizeof(Texture_Struct) * textures::TextureCount));
|
||||
}
|
||||
|
||||
EQEmu::TextureShortProfile::TextureShortProfile()
|
||||
{
|
||||
memset(&Slot, 0, (sizeof(uint32) * textures::TextureCount));
|
||||
}
|
||||
|
||||
EQEmu::TintProfile::TintProfile()
|
||||
{
|
||||
memset(&Slot, 0, (sizeof(uint32) * textures::TextureCount));
|
||||
}
|
||||
|
||||
+84
-81
@@ -25,113 +25,116 @@
|
||||
|
||||
namespace EQEmu
|
||||
{
|
||||
//class InventorySlot;
|
||||
|
||||
namespace textures {
|
||||
enum : int8 { textureInvalid = -1, textureBegin };
|
||||
//enum : int { TextureInvalid = -1, TextureBegin };
|
||||
enum : uint8 { TextureInvalid = 255, TextureBegin = 0 };
|
||||
|
||||
enum TextureSlot : int8 {
|
||||
armorHead = textureBegin,
|
||||
armorChest,
|
||||
armorArms,
|
||||
armorWrist,
|
||||
armorHands,
|
||||
armorLegs,
|
||||
armorFeet,
|
||||
weaponPrimary,
|
||||
weaponSecondary,
|
||||
materialCount,
|
||||
materialInvalid = textureInvalid
|
||||
//enum TextureSlot : int {
|
||||
enum TextureSlot : uint8 {
|
||||
TextureHead = TextureBegin,
|
||||
TextureChest,
|
||||
TextureArms,
|
||||
TextureWrist,
|
||||
TextureHands,
|
||||
TextureLegs,
|
||||
TextureFeet,
|
||||
TexturePrimary,
|
||||
TextureSecondary,
|
||||
TextureCount
|
||||
};
|
||||
|
||||
enum TintSlot : int8 {
|
||||
tintHead = textureBegin,
|
||||
tintChest,
|
||||
tintArms,
|
||||
tintWrist,
|
||||
tintHands,
|
||||
tintLegs,
|
||||
tintFeet,
|
||||
tintCount,
|
||||
tintInvalid = textureInvalid
|
||||
};
|
||||
const int LastTexture = TextureSecondary;
|
||||
const int LastTintableTexture = TextureFeet;
|
||||
|
||||
const int8 LastTexture = weaponSecondary;
|
||||
const int8 LastTintableTexture = tintFeet;
|
||||
|
||||
struct Texture_Struct {
|
||||
uint32 Material;
|
||||
uint32 Unknown1;
|
||||
uint32 EliteModel;
|
||||
uint32 HerosForgeModel;
|
||||
uint32 Unknown2; // same as material?
|
||||
};
|
||||
|
||||
struct TextureMaterial_Struct {
|
||||
uint32 Material;
|
||||
};
|
||||
|
||||
struct Tint_Struct {
|
||||
union {
|
||||
struct {
|
||||
uint8 Blue;
|
||||
uint8 Green;
|
||||
uint8 Red;
|
||||
uint8 UseTint; // if there's a tint, this is FF
|
||||
};
|
||||
uint32 Color;
|
||||
};
|
||||
};
|
||||
//extern int ConvertEquipmentSlotToTextureSlot(int equipment_slot);
|
||||
//extern int ConvertEquipmentSlotToTextureSlot(const InventorySlot &equipment_slot);
|
||||
//extern InventorySlot ConvertTextureSlotToEquipmentSlot(int texture_slot);
|
||||
|
||||
} /*textures*/
|
||||
|
||||
struct Texture_Struct {
|
||||
uint32 Material;
|
||||
uint32 Unknown1;
|
||||
uint32 EliteMaterial;
|
||||
uint32 HeroForgeModel;
|
||||
uint32 Material2; // Same as material?
|
||||
};
|
||||
|
||||
struct TextureProfile {
|
||||
union {
|
||||
struct {
|
||||
textures::Texture_Struct Head;
|
||||
textures::Texture_Struct Chest;
|
||||
textures::Texture_Struct Arms;
|
||||
textures::Texture_Struct Wrist;
|
||||
textures::Texture_Struct Hands;
|
||||
textures::Texture_Struct Legs;
|
||||
textures::Texture_Struct Feet;
|
||||
textures::Texture_Struct Primary;
|
||||
textures::Texture_Struct Secondary;
|
||||
Texture_Struct Head;
|
||||
Texture_Struct Chest;
|
||||
Texture_Struct Arms;
|
||||
Texture_Struct Wrist;
|
||||
Texture_Struct Hands;
|
||||
Texture_Struct Legs;
|
||||
Texture_Struct Feet;
|
||||
Texture_Struct Primary;
|
||||
Texture_Struct Secondary;
|
||||
};
|
||||
textures::Texture_Struct Slot[textures::materialCount];
|
||||
Texture_Struct Slot[textures::TextureCount];
|
||||
};
|
||||
|
||||
TextureProfile();
|
||||
};
|
||||
|
||||
struct TextureMaterialProfile {
|
||||
struct TextureShort_Struct {
|
||||
uint32 Material;
|
||||
};
|
||||
|
||||
struct TextureShortProfile {
|
||||
union {
|
||||
struct {
|
||||
textures::TextureMaterial_Struct Head;
|
||||
textures::TextureMaterial_Struct Chest;
|
||||
textures::TextureMaterial_Struct Arms;
|
||||
textures::TextureMaterial_Struct Wrist;
|
||||
textures::TextureMaterial_Struct Hands;
|
||||
textures::TextureMaterial_Struct Legs;
|
||||
textures::TextureMaterial_Struct Feet;
|
||||
textures::TextureMaterial_Struct Primary;
|
||||
textures::TextureMaterial_Struct Secondary;
|
||||
TextureShort_Struct Head;
|
||||
TextureShort_Struct Chest;
|
||||
TextureShort_Struct Arms;
|
||||
TextureShort_Struct Wrist;
|
||||
TextureShort_Struct Hands;
|
||||
TextureShort_Struct Legs;
|
||||
TextureShort_Struct Feet;
|
||||
TextureShort_Struct Primary;
|
||||
TextureShort_Struct Secondary;
|
||||
};
|
||||
textures::TextureMaterial_Struct Slot[textures::materialCount];
|
||||
TextureShort_Struct Slot[textures::TextureCount];
|
||||
};
|
||||
|
||||
TextureShortProfile();
|
||||
};
|
||||
|
||||
struct Tint_Struct {
|
||||
union {
|
||||
struct {
|
||||
uint8 Blue;
|
||||
uint8 Green;
|
||||
uint8 Red;
|
||||
uint8 UseTint; // if there's a tint this is FF
|
||||
};
|
||||
uint32 Color;
|
||||
};
|
||||
|
||||
//Tint_Struct();
|
||||
};
|
||||
|
||||
struct TintProfile {
|
||||
union {
|
||||
struct {
|
||||
textures::Tint_Struct Head;
|
||||
textures::Tint_Struct Chest;
|
||||
textures::Tint_Struct Arms;
|
||||
textures::Tint_Struct Wrist;
|
||||
textures::Tint_Struct Hands;
|
||||
textures::Tint_Struct Legs;
|
||||
textures::Tint_Struct Feet;
|
||||
textures::Tint_Struct Primary;
|
||||
textures::Tint_Struct Secondary;
|
||||
Tint_Struct Head;
|
||||
Tint_Struct Chest;
|
||||
Tint_Struct Arms;
|
||||
Tint_Struct Wrist;
|
||||
Tint_Struct Hands;
|
||||
Tint_Struct Legs;
|
||||
Tint_Struct Feet;
|
||||
Tint_Struct Primary;
|
||||
Tint_Struct Secondary;
|
||||
};
|
||||
textures::Tint_Struct Slot[textures::materialCount]; // materialCount is correct..but, {[weaponPrimary],[weaponSecondary]} are not tintable...
|
||||
Tint_Struct Slot[textures::TextureCount];
|
||||
};
|
||||
|
||||
TintProfile();
|
||||
};
|
||||
|
||||
} /*EQEmu*/
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
EQEMu: Everquest Server Emulator
|
||||
Copyright (C) 2001-2014 EQEMu Development Team (http://eqemulator.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; version 2 of the License.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY except by those people which sell it, which
|
||||
are required to give you total support for your newly bought product;
|
||||
without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public 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 "uuid.h"
|
||||
|
||||
#ifdef WIN32
|
||||
#include <rpc.h>
|
||||
#else
|
||||
#include <uuid/uuid.h>
|
||||
#endif
|
||||
|
||||
std::string CreateUUID() {
|
||||
#ifdef WIN32
|
||||
UUID uuid;
|
||||
UuidCreate(&uuid);
|
||||
unsigned char *str = nullptr;
|
||||
UuidToStringA(&uuid, &str);
|
||||
std::string s((char*)str);
|
||||
RpcStringFreeA(&str);
|
||||
return s;
|
||||
#else
|
||||
char str[64] = { 0 };
|
||||
uuid_t uuid;
|
||||
uuid_generate_random(uuid);
|
||||
uuid_unparse(uuid, str);
|
||||
return str;
|
||||
#endif
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
/*
|
||||
EQEMu: Everquest Server Emulator
|
||||
Copyright (C) 2001-2014 EQEMu Development Team (http://eqemulator.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; version 2 of the License.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY except by those people which sell it, which
|
||||
are required to give you total support for your newly bought product;
|
||||
without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public 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 COMMON_UUID_H
|
||||
#define COMMON_UUID_H
|
||||
|
||||
#include <string>
|
||||
|
||||
std::string CreateUUID();
|
||||
|
||||
#endif
|
||||
|
||||
+1
-1
@@ -30,7 +30,7 @@
|
||||
Manifest: https://github.com/EQEmu/Server/blob/master/utils/sql/db_update_manifest.txt
|
||||
*/
|
||||
|
||||
#define CURRENT_BINARY_DATABASE_VERSION 9101
|
||||
#define CURRENT_BINARY_DATABASE_VERSION 9097
|
||||
#ifdef BOTS
|
||||
#define CURRENT_BINARY_BOTS_DATABASE_VERSION 9008
|
||||
#else
|
||||
|
||||
@@ -0,0 +1,77 @@
|
||||
/* EQEMu: Everquest Server Emulator
|
||||
Copyright (C) 2001-2014 EQEMu Development Team (http://eqemulator.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; version 2 of the License.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY except by those people which sell it, which
|
||||
are required to give you total support for your newly bought product;
|
||||
without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public 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/global_define.h"
|
||||
#include "web_interface_utils.h"
|
||||
#include "rapidjson/writer.h"
|
||||
#include "rapidjson/stringbuffer.h"
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <vector>
|
||||
#include <utility>
|
||||
|
||||
|
||||
using namespace rapidjson;
|
||||
using namespace std;
|
||||
|
||||
std::vector<std::string> explode_string(std::string const & s, char delim)
|
||||
{
|
||||
std::vector<std::string> result;
|
||||
std::istringstream iss(s);
|
||||
|
||||
for (std::string token; std::getline(iss, token, delim);)
|
||||
{
|
||||
result.push_back(std::move(token));
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
std::string MakeJSON(std::string json)
|
||||
{
|
||||
StringBuffer s;
|
||||
Writer<StringBuffer> writer(s);
|
||||
writer.StartObject();
|
||||
|
||||
auto arg_c = explode_string(json, ',');
|
||||
if (arg_c.size() == 0)
|
||||
{
|
||||
auto arg_v = explode_string(json, ':');
|
||||
if (arg_v.size() > 0)
|
||||
{
|
||||
for (int j = 0; j < arg_v.size(); j++)
|
||||
{
|
||||
writer.String(arg_v[j].c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int i = 0; i < arg_c.size(); i++)
|
||||
{
|
||||
auto arg_v = explode_string(arg_c[i], ':');
|
||||
for (int j = 0; j < arg_v.size(); j++)
|
||||
{
|
||||
writer.String(arg_v[j].c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
writer.EndObject();
|
||||
return s.GetString();
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
/* EQEMu: Everquest Server Emulator
|
||||
Copyright (C) 2001-2014 EQEMu Development Team (http://eqemulator.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; version 2 of the License.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY except by those people which sell it, which
|
||||
are required to give you total support for your newly bought product;
|
||||
without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public 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 COMMON_WEBINTUTIL_H
|
||||
#define COMMON_WEBINTUTIL_H
|
||||
|
||||
#include "../common/global_define.h"
|
||||
#include "rapidjson/writer.h"
|
||||
#include "rapidjson/stringbuffer.h"
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <vector>
|
||||
#include <utility>
|
||||
|
||||
std::vector<std::string> explode_string(std::string const & s, char delim);
|
||||
std::string MakeJSON(std::string json);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,2 +1,9 @@
|
||||
*.*
|
||||
*
|
||||
boost/
|
||||
luaj_x86/
|
||||
luaj_x64/
|
||||
mysql_x86/
|
||||
mysql_x64/
|
||||
zlib_x86/
|
||||
zlib_x64/
|
||||
cyassl/
|
||||
websocketpp/
|
||||
Vendored
+7
@@ -0,0 +1,7 @@
|
||||
CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
|
||||
|
||||
IF(EQEMU_BUILD_LUA)
|
||||
ADD_SUBDIRECTORY(luabind)
|
||||
ENDIF(EQEMU_BUILD_LUA)
|
||||
|
||||
ADD_SUBDIRECTORY(libwebsockets)
|
||||
@@ -0,0 +1,38 @@
|
||||
#Ignore build files
|
||||
Makefile
|
||||
config.h
|
||||
config.log
|
||||
config.status
|
||||
libtool
|
||||
stamp-h1
|
||||
output/
|
||||
win32port/ipch/
|
||||
win32port/Debug*/
|
||||
win32port/Release*/
|
||||
win32port/server/Debug*/
|
||||
win32port/server/Release*/
|
||||
win32port/client/Debug*/
|
||||
win32port/client/Release*/
|
||||
win32port/libwebsocketswin32/Debug*/
|
||||
win32port/libwebsocketswin32/Release*/
|
||||
win32port/zlib/Debug*/
|
||||
win32port/zlib/Release*/
|
||||
*.vcxproj.user
|
||||
*.opensdf
|
||||
*.sdf
|
||||
*.suo
|
||||
*.su
|
||||
*.m4
|
||||
missing
|
||||
depcomp
|
||||
install-sh
|
||||
configure
|
||||
compile
|
||||
config.guess
|
||||
*~
|
||||
*.orig
|
||||
autom4te.cache/
|
||||
ltmain.sh
|
||||
config.sub
|
||||
ar-lib
|
||||
libwebsockets.pc
|
||||
+29
@@ -0,0 +1,29 @@
|
||||
# example Android Native Library makefile
|
||||
# contributed by Gregory Junker <ggjunker@gmail.com>
|
||||
|
||||
LOCAL_PATH:= $(call my-dir)
|
||||
|
||||
include $(CLEAR_VARS)
|
||||
|
||||
LOCAL_MODULE := libwebsockets
|
||||
LOCAL_CFLAGS := -DLWS_BUILTIN_GETIFADDRS
|
||||
LWS_LIB_PATH := ../../../shared/libwebsockets/lib
|
||||
LOCAL_C_INCLUDES:= $(LOCAL_PATH)/$(LWS_LIB_PATH)
|
||||
LOCAL_SRC_FILES := \
|
||||
$(LWS_LIB_PATH)/base64-decode.c \
|
||||
$(LWS_LIB_PATH)/client.c \
|
||||
$(LWS_LIB_PATH)/client-handshake.c \
|
||||
$(LWS_LIB_PATH)/client-parser.c \
|
||||
$(LWS_LIB_PATH)/daemonize.c \
|
||||
$(LWS_LIB_PATH)/extension.c \
|
||||
$(LWS_LIB_PATH)/extension-deflate-frame.c \
|
||||
$(LWS_LIB_PATH)/extension-deflate-stream.c \
|
||||
$(LWS_LIB_PATH)/getifaddrs.c \
|
||||
$(LWS_LIB_PATH)/handshake.c \
|
||||
$(LWS_LIB_PATH)/libwebsockets.c \
|
||||
$(LWS_LIB_PATH)/md5.c \
|
||||
$(LWS_LIB_PATH)/output.c \
|
||||
$(LWS_LIB_PATH)/parsers.c \
|
||||
$(LWS_LIB_PATH)/sha-1.c
|
||||
|
||||
include $(BUILD_STATIC_LIBRARY)
|
||||
+927
@@ -0,0 +1,927 @@
|
||||
cmake_minimum_required(VERSION 2.6)
|
||||
|
||||
if(POLICY CMP0046)
|
||||
cmake_policy(VERSION 2.8)
|
||||
# The new policy for add_dependencies is to now error if a dependency target
|
||||
# is not found. The old policy didn't care and continued through configuration
|
||||
cmake_policy(SET CMP0046 OLD)
|
||||
endif()
|
||||
|
||||
project(libwebsockets)
|
||||
|
||||
set(PACKAGE "libwebsockets")
|
||||
set(CPACK_PACKAGE_NAME "${PACKAGE}")
|
||||
set(CPACK_PACKAGE_VERSION_MAJOR "1")
|
||||
set(CPACK_PACKAGE_VERSION_MINOR "3")
|
||||
set(CPACK_PACKAGE_VERSION "${CPACK_PACKAGE_VERSION_MAJOR}.${CPACK_PACKAGE_VERSION_MINOR}")
|
||||
set(CPACK_PACKAGE_VENDOR "andy@warmcat.com")
|
||||
set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "${PACKAGE} ${PACKAGE_VERSION}")
|
||||
set(SOVERSION "4.0.0")
|
||||
set(CPACK_SOURCE_GENERATOR "TGZ")
|
||||
set(CPACK_SOURCE_PACKAGE_FILE_NAME "${CPACK_PACKAGE_NAME}-${CPACK_PACKAGE_VERSION}")
|
||||
set(VERSION "${CPACK_PACKAGE_VERSION}")
|
||||
|
||||
set(LWS_LIBRARY_VERSION ${CPACK_PACKAGE_VERSION})
|
||||
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${PROJECT_SOURCE_DIR}/cmake/")
|
||||
|
||||
message(STATUS "CMAKE_TOOLCHAIN_FILE='${CMAKE_TOOLCHAIN_FILE}'")
|
||||
|
||||
# Try to find the current Git hash.
|
||||
find_package(Git)
|
||||
if(GIT_EXECUTABLE)
|
||||
execute_process(
|
||||
WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
|
||||
COMMAND "${GIT_EXECUTABLE}" log -n 1 --pretty=%h
|
||||
OUTPUT_VARIABLE GIT_HASH
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE
|
||||
)
|
||||
|
||||
set(LWS_BUILD_HASH ${GIT_HASH})
|
||||
message("Git commit hash: ${LWS_BUILD_HASH}")
|
||||
endif()
|
||||
|
||||
option(LWS_WITH_SSL "Include SSL support (default OpenSSL, CyaSSL if LWS_USE_CYASSL is set)" OFF)
|
||||
option(LWS_SSL_CLIENT_USE_OS_CA_CERTS "SSL support should make use of OS installed CA root certs" ON)
|
||||
option(LWS_USE_EXTERNAL_ZLIB "Search the system for ZLib instead of using the included one (on Windows)" OFF)
|
||||
option(LWS_USE_CYASSL "Use CyaSSL replacement for OpenSSL. When settings this, you also need to specify LWS_CYASSL_LIB and LWS_CYASSL_INCLUDE_DIRS" OFF)
|
||||
option(LWS_WITHOUT_BUILTIN_GETIFADDRS "Don't use BSD getifaddrs implementation from libwebsockets if it is missing (this will result in a compilation error) ... Default is your libc provides it. On some systems such as uclibc it doesn't exist." OFF)
|
||||
option(LWS_WITHOUT_CLIENT "Don't build the client part of the library" ON)
|
||||
option(LWS_WITHOUT_SERVER "Don't build the server part of the library" OFF)
|
||||
option(LWS_LINK_TESTAPPS_DYNAMIC "Link the test apps to the shared version of the library. Default is to link statically" ON)
|
||||
option(LWS_WITHOUT_TESTAPPS "Don't build the libwebsocket-test-apps" ON)
|
||||
option(LWS_WITHOUT_TEST_SERVER "Don't build the test server" ON)
|
||||
option(LWS_WITHOUT_TEST_SERVER_EXTPOLL "Don't build the test server version that uses external poll" ON)
|
||||
option(LWS_WITHOUT_TEST_PING "Don't build the ping test application" ON)
|
||||
option(LWS_WITHOUT_TEST_CLIENT "Don't build the client test application" ON)
|
||||
option(LWS_WITHOUT_TEST_FRAGGLE "Don't build the ping test application" ON)
|
||||
option(LWS_WITHOUT_DEBUG "Don't compile debug related code" OFF)
|
||||
option(LWS_WITHOUT_EXTENSIONS "Don't compile with extensions" OFF)
|
||||
option(LWS_WITH_LATENCY "Build latency measuring code into the library" OFF)
|
||||
option(LWS_WITHOUT_DAEMONIZE "Don't build the daemonization api" OFF)
|
||||
option(LWS_WITH_LIBEV "Compile with support for libev" OFF)
|
||||
option(LWS_IPV6 "Compile with support for ipv6" ON)
|
||||
option(LWS_WITH_HTTP2 "Compile with support for http2" OFF)
|
||||
|
||||
# Allow the user to override installation directories.
|
||||
set(LWS_INSTALL_LIB_DIR lib CACHE PATH "Installation directory for libraries")
|
||||
set(LWS_INSTALL_BIN_DIR "." CACHE PATH "Installation directory for executables")
|
||||
set(LWS_INSTALL_INCLUDE_DIR include CACHE PATH "Installation directory for header files")
|
||||
set(LWS_INSTALL_EXAMPLES_DIR "." CACHE PATH "Installation directory for example files")
|
||||
|
||||
if (LWS_WITHOUT_CLIENT AND LWS_WITHOUT_SERVER)
|
||||
message(FATAL_ERROR "Makes no sense to compile without both client or server.")
|
||||
endif()
|
||||
|
||||
# The base dir where the test-apps look for the SSL certs.
|
||||
set(LWS_OPENSSL_CLIENT_CERTS ../share CACHE PATH "Server SSL certificate directory")
|
||||
if (WIN32)
|
||||
set(LWS_OPENSSL_CLIENT_CERTS . CACHE PATH "Client SSL certificate directory")
|
||||
|
||||
if (LWS_IPV6)
|
||||
set(LWS_IPV6 OFF)
|
||||
message(WARNING "IPv6 does currently not work on Windows!")
|
||||
endif()
|
||||
else()
|
||||
set(LWS_OPENSSL_CLIENT_CERTS /etc/pki/tls/certs/ CACHE PATH "Client SSL certificate directory")
|
||||
endif()
|
||||
|
||||
set(LWS_CYASSL_LIB CACHE PATH "Path to the CyaSSL library")
|
||||
set(LWS_CYASSL_INCLUDE_DIRS CACHE PATH "Path to the CyaSSL include directory")
|
||||
|
||||
if (LWS_USE_CYASSL)
|
||||
if ("${LWS_CYASSL_LIB}" STREQUAL "" OR "${LWS_CYASSL_INCLUDE_DIRS}" STREQUAL "")
|
||||
message(FATAL_ERROR "You must set LWS_CYASSL_LIB and LWS_CYASSL_INCLUDE_DIRS when LWS_USE_CYASSL is turned on")
|
||||
endif()
|
||||
set(USE_CYASSL 1)
|
||||
endif()
|
||||
|
||||
if (LWS_WITHOUT_EXTENSIONS)
|
||||
set(LWS_NO_EXTENSIONS 1)
|
||||
endif()
|
||||
|
||||
if (LWS_WITH_SSL)
|
||||
set(LWS_OPENSSL_SUPPORT 1)
|
||||
endif()
|
||||
|
||||
if (LWS_SSL_CLIENT_USE_OS_CA_CERTS)
|
||||
set(LWS_SSL_CLIENT_USE_OS_CA_CERTS 1)
|
||||
endif()
|
||||
|
||||
if (LWS_WITH_LATENCY)
|
||||
set(LWS_LATENCY 1)
|
||||
endif()
|
||||
|
||||
if (LWS_WITHOUT_DAEMONIZE OR WIN32)
|
||||
set(LWS_NO_DAEMONIZE 1)
|
||||
endif()
|
||||
|
||||
if (LWS_WITHOUT_SERVER)
|
||||
set(LWS_NO_SERVER 1)
|
||||
endif()
|
||||
|
||||
if (LWS_WITHOUT_CLIENT)
|
||||
set(LWS_NO_CLIENT 1)
|
||||
endif()
|
||||
|
||||
if (LWS_WITHOUT_DEBUG)
|
||||
set(_DEBUG 0)
|
||||
else()
|
||||
set(_DEBUG 1)
|
||||
endif()
|
||||
|
||||
if (LWS_WITH_LIBEV)
|
||||
set(LWS_USE_LIBEV 1)
|
||||
set(LWS_NO_EXTERNAL_POLL 1)
|
||||
endif()
|
||||
|
||||
if (LWS_IPV6)
|
||||
set(LWS_USE_IPV6 1)
|
||||
endif()
|
||||
|
||||
if (LWS_WITH_HTTP2)
|
||||
set(LWS_USE_HTTP2 1)
|
||||
endif()
|
||||
|
||||
if (MINGW)
|
||||
set(LWS_MINGW_SUPPORT 1)
|
||||
endif()
|
||||
|
||||
include_directories("${PROJECT_BINARY_DIR}")
|
||||
|
||||
include(CheckCSourceCompiles)
|
||||
|
||||
# Check for different inline keyword versions.
|
||||
foreach(KEYWORD "inline" "__inline__" "__inline")
|
||||
set(CMAKE_REQUIRED_DEFINITIONS "-DKEYWORD=${KEYWORD}")
|
||||
CHECK_C_SOURCE_COMPILES(
|
||||
"
|
||||
#include <stdio.h>
|
||||
KEYWORD void a() {}
|
||||
int main(int argc, char **argv) { a(); return 0; }
|
||||
" HAVE_${KEYWORD})
|
||||
endforeach()
|
||||
|
||||
if (NOT HAVE_inline)
|
||||
if (HAVE___inline__)
|
||||
set(inline __inline__)
|
||||
elseif(HAVE___inline)
|
||||
set(inline __inline)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# Put the libaries and binaries that get built into directories at the
|
||||
# top of the build tree rather than in hard-to-find leaf directories.
|
||||
SET(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/bin")
|
||||
SET(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/lib")
|
||||
SET(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/lib")
|
||||
|
||||
# Put absolute path of dynamic libraries into the object code. Some
|
||||
# architectures, notably Mac OS X, need this.
|
||||
SET(CMAKE_INSTALL_NAME_DIR "${CMAKE_INSTALL_PREFIX}/${LWS_INSTALL_LIB_DIR}${LIB_SUFFIX}")
|
||||
|
||||
# So we can include the CMake generated config file only when
|
||||
# building with CMAKE.
|
||||
add_definitions(-DCMAKE_BUILD)
|
||||
|
||||
include(CheckFunctionExists)
|
||||
include(CheckIncludeFile)
|
||||
include(CheckIncludeFiles)
|
||||
include(CheckLibraryExists)
|
||||
include(CheckTypeSize)
|
||||
|
||||
CHECK_FUNCTION_EXISTS(bzero HAVE_BZERO)
|
||||
CHECK_FUNCTION_EXISTS(fork HAVE_FORK)
|
||||
CHECK_FUNCTION_EXISTS(getenv HAVE_GETENV)
|
||||
CHECK_FUNCTION_EXISTS(malloc HAVE_MALLOC)
|
||||
CHECK_FUNCTION_EXISTS(memset HAVE_MEMSET)
|
||||
CHECK_FUNCTION_EXISTS(realloc HAVE_REALLOC)
|
||||
CHECK_FUNCTION_EXISTS(socket HAVE_SOCKET)
|
||||
CHECK_FUNCTION_EXISTS(strerror HAVE_STRERROR)
|
||||
CHECK_FUNCTION_EXISTS(vfork HAVE_VFORK)
|
||||
CHECK_FUNCTION_EXISTS(getifaddrs HAVE_GETIFADDRS)
|
||||
|
||||
if (NOT HAVE_GETIFADDRS)
|
||||
if (LWS_WITHOUT_BUILTIN_GETIFADDRS)
|
||||
message(FATAL_ERROR "No getifaddrs was found on the system. Turn off the LWS_WITHOUT_BUILTIN_GETIFADDRS compile option to use the supplied BSD version.")
|
||||
endif()
|
||||
|
||||
set(LWS_BUILTIN_GETIFADDRS 1)
|
||||
endif()
|
||||
|
||||
CHECK_INCLUDE_FILE(dlfcn.h HAVE_DLFCN_H)
|
||||
CHECK_INCLUDE_FILE(fcntl.h HAVE_FCNTL_H)
|
||||
CHECK_INCLUDE_FILE(in6addr.h HAVE_IN6ADDR_H)
|
||||
CHECK_INCLUDE_FILE(inttypes.h HAVE_INTTYPES_H)
|
||||
CHECK_INCLUDE_FILE(memory.h HAVE_MEMORY_H)
|
||||
CHECK_INCLUDE_FILE(netinet/in.h HAVE_NETINET_IN_H)
|
||||
CHECK_INCLUDE_FILE(stdint.h HAVE_STDINT_H)
|
||||
CHECK_INCLUDE_FILE(stdlib.h HAVE_STDLIB_H)
|
||||
CHECK_INCLUDE_FILE(strings.h HAVE_STRINGS_H)
|
||||
CHECK_INCLUDE_FILE(string.h HAVE_STRING_H)
|
||||
CHECK_INCLUDE_FILE(sys/prctl.h HAVE_SYS_PRCTL_H)
|
||||
CHECK_INCLUDE_FILE(sys/socket.h HAVE_SYS_SOCKET_H)
|
||||
CHECK_INCLUDE_FILE(sys/stat.h HAVE_SYS_STAT_H)
|
||||
CHECK_INCLUDE_FILE(sys/types.h HAVE_SYS_TYPES_H)
|
||||
CHECK_INCLUDE_FILE(unistd.h HAVE_UNISTD_H)
|
||||
CHECK_INCLUDE_FILE(vfork.h HAVE_VFORK_H)
|
||||
CHECK_INCLUDE_FILE(zlib.h HAVE_ZLIB_H)
|
||||
|
||||
# TODO: These can be tested if they actually work also...
|
||||
set(HAVE_WORKING_FORK HAVE_FORK)
|
||||
set(HAVE_WORKING_VFORK HAVE_VFORK)
|
||||
|
||||
CHECK_INCLUDE_FILES("stdlib.h;stdarg.h;string.h;float.h" STDC_HEADERS)
|
||||
|
||||
CHECK_TYPE_SIZE(pid_t PID_T_SIZE)
|
||||
CHECK_TYPE_SIZE(size_t SIZE_T_SIZE)
|
||||
|
||||
if (NOT PID_T_SIZE)
|
||||
set(pid_t int)
|
||||
endif()
|
||||
|
||||
if (NOT SIZE_T_SIZE)
|
||||
set(size_t "unsigned int")
|
||||
endif()
|
||||
|
||||
if (NOT HAVE_MALLOC)
|
||||
set(malloc rpl_malloc)
|
||||
endif()
|
||||
|
||||
if (NOT HAVE_REALLOC)
|
||||
set(realloc rpl_realloc)
|
||||
endif()
|
||||
|
||||
# Generate the config.h that includes all the compilation settings.
|
||||
configure_file(
|
||||
"${PROJECT_SOURCE_DIR}/config.h.cmake"
|
||||
"${PROJECT_BINARY_DIR}/lws_config.h")
|
||||
|
||||
if (MSVC)
|
||||
# Turn off stupid microsoft security warnings.
|
||||
add_definitions(-D_CRT_SECURE_NO_DEPRECATE -D_CRT_NONSTDC_NO_DEPRECATE)
|
||||
endif(MSVC)
|
||||
|
||||
include_directories("${PROJECT_SOURCE_DIR}/lib")
|
||||
|
||||
# Group headers and sources.
|
||||
# Some IDEs use this for nicer file structure.
|
||||
set(HDR_PRIVATE
|
||||
lib/private-libwebsockets.h
|
||||
"${PROJECT_BINARY_DIR}/lws_config.h"
|
||||
)
|
||||
|
||||
set(HDR_PUBLIC
|
||||
"${PROJECT_SOURCE_DIR}/lib/libwebsockets.h"
|
||||
)
|
||||
|
||||
set(SOURCES
|
||||
lib/base64-decode.c
|
||||
lib/handshake.c
|
||||
lib/libwebsockets.c
|
||||
lib/service.c
|
||||
lib/pollfd.c
|
||||
lib/output.c
|
||||
lib/parsers.c
|
||||
lib/context.c
|
||||
lib/sha-1.c
|
||||
)
|
||||
|
||||
if (NOT LWS_WITHOUT_CLIENT)
|
||||
list(APPEND SOURCES
|
||||
lib/client.c
|
||||
lib/client-handshake.c
|
||||
lib/client-parser.c
|
||||
)
|
||||
endif()
|
||||
|
||||
if (LWS_WITH_SSL)
|
||||
list(APPEND SOURCES
|
||||
lib/ssl.c
|
||||
)
|
||||
endif()
|
||||
|
||||
if (LWS_WITH_HTTP2)
|
||||
list(APPEND SOURCES
|
||||
lib/ssl-http2.c
|
||||
)
|
||||
endif()
|
||||
# select the active platform files
|
||||
|
||||
if (WIN32)
|
||||
list(APPEND SOURCES
|
||||
lib/lws-plat-win.c
|
||||
)
|
||||
else()
|
||||
list(APPEND SOURCES
|
||||
lib/lws-plat-unix.c
|
||||
)
|
||||
endif()
|
||||
|
||||
if (NOT LWS_WITHOUT_SERVER)
|
||||
list(APPEND SOURCES
|
||||
lib/server.c
|
||||
lib/server-handshake.c
|
||||
)
|
||||
endif()
|
||||
|
||||
if (NOT LWS_WITHOUT_EXTENSIONS)
|
||||
list(APPEND HDR_PRIVATE
|
||||
lib/extension-deflate-frame.h
|
||||
lib/extension-deflate-stream.h
|
||||
)
|
||||
|
||||
list(APPEND SOURCES
|
||||
lib/extension.c
|
||||
lib/extension-deflate-frame.c
|
||||
lib/extension-deflate-stream.c
|
||||
)
|
||||
endif()
|
||||
|
||||
if (LWS_WITH_LIBEV)
|
||||
list(APPEND SOURCES
|
||||
lib/libev.c
|
||||
)
|
||||
endif(LWS_WITH_LIBEV)
|
||||
|
||||
# Add helper files for Windows.
|
||||
if (WIN32)
|
||||
set(WIN32_HELPERS_PATH win32port/win32helpers)
|
||||
include_directories(${WIN32_HELPERS_PATH})
|
||||
else(WIN32)
|
||||
# Unix.
|
||||
if (NOT LWS_WITHOUT_DAEMONIZE)
|
||||
list(APPEND SOURCES
|
||||
lib/daemonize.c
|
||||
)
|
||||
endif()
|
||||
endif(WIN32)
|
||||
|
||||
if (UNIX)
|
||||
if (NOT HAVE_GETIFADDRS)
|
||||
list(APPEND HDR_PRIVATE lib/getifaddrs.h)
|
||||
list(APPEND SOURCES lib/getifaddrs.c)
|
||||
endif()
|
||||
endif(UNIX)
|
||||
|
||||
|
||||
if (CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_GNUCXX)
|
||||
if (UNIX)
|
||||
set( CMAKE_C_FLAGS "-Wall -Werror -O4 -fvisibility=hidden ${CMAKE_C_FLAGS}" )
|
||||
else(UNIX)
|
||||
set( CMAKE_C_FLAGS "-Wall -O4 -fvisibility=hidden ${CMAKE_C_FLAGS}" )
|
||||
endif(UNIX)
|
||||
endif ()
|
||||
|
||||
source_group("Headers Private" FILES ${HDR_PRIVATE})
|
||||
source_group("Headers Public" FILES ${HDR_PUBLIC})
|
||||
source_group("Sources" FILES ${SOURCES})
|
||||
|
||||
#
|
||||
# Create the lib.
|
||||
#
|
||||
add_library(websockets STATIC
|
||||
${HDR_PRIVATE}
|
||||
${HDR_PUBLIC}
|
||||
${SOURCES})
|
||||
add_library(websockets_shared SHARED
|
||||
${HDR_PRIVATE}
|
||||
${HDR_PUBLIC}
|
||||
${SOURCES})
|
||||
|
||||
if (WIN32)
|
||||
# On Windows libs have the same file ending (.lib)
|
||||
# for both static and shared libraries, so we
|
||||
# need a unique name for the static one.
|
||||
set_target_properties(websockets
|
||||
PROPERTIES
|
||||
OUTPUT_NAME websockets_static)
|
||||
|
||||
# Compile as DLL (export function declarations)
|
||||
set_property(
|
||||
TARGET websockets_shared
|
||||
PROPERTY COMPILE_DEFINITIONS
|
||||
LWS_DLL
|
||||
LWS_INTERNAL
|
||||
)
|
||||
endif(WIN32)
|
||||
|
||||
# We want the shared lib to be named "libwebsockets"
|
||||
# not "libwebsocket_shared".
|
||||
set_target_properties(websockets_shared
|
||||
PROPERTIES
|
||||
OUTPUT_NAME websockets)
|
||||
|
||||
# Set the so version of the lib.
|
||||
# Equivalent to LDFLAGS=-version-info x:x:x
|
||||
if(CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_GNUCXX)
|
||||
foreach(lib websockets websockets_shared)
|
||||
set_target_properties(${lib}
|
||||
PROPERTIES
|
||||
SOVERSION ${SOVERSION})
|
||||
endforeach()
|
||||
endif()
|
||||
|
||||
set(LIB_LIST)
|
||||
|
||||
#
|
||||
# Find libraries.
|
||||
#
|
||||
|
||||
#
|
||||
# ZLIB (Only needed for deflate extensions).
|
||||
#
|
||||
if (NOT LWS_WITHOUT_EXTENSIONS)
|
||||
if (WIN32 AND NOT LWS_USE_EXTERNAL_ZLIB)
|
||||
message("Using included Zlib version")
|
||||
|
||||
# Compile ZLib if needed.
|
||||
set(WIN32_ZLIB_PATH "win32port/zlib")
|
||||
set(ZLIB_SRCS
|
||||
${WIN32_ZLIB_PATH}/adler32.c
|
||||
${WIN32_ZLIB_PATH}/compress.c
|
||||
${WIN32_ZLIB_PATH}/crc32.c
|
||||
${WIN32_ZLIB_PATH}/deflate.c
|
||||
${WIN32_ZLIB_PATH}/gzclose.c
|
||||
${WIN32_ZLIB_PATH}/gzio.c
|
||||
${WIN32_ZLIB_PATH}/gzlib.c
|
||||
${WIN32_ZLIB_PATH}/gzread.c
|
||||
${WIN32_ZLIB_PATH}/gzwrite.c
|
||||
${WIN32_ZLIB_PATH}/infback.c
|
||||
${WIN32_ZLIB_PATH}/inffast.c
|
||||
${WIN32_ZLIB_PATH}/inflate.c
|
||||
${WIN32_ZLIB_PATH}/inftrees.c
|
||||
${WIN32_ZLIB_PATH}/trees.c
|
||||
${WIN32_ZLIB_PATH}/uncompr.c
|
||||
${WIN32_ZLIB_PATH}/zutil.c
|
||||
)
|
||||
|
||||
# Create the library.
|
||||
add_library(ZLIB STATIC ${ZLIB_SRCS})
|
||||
|
||||
# Set the same variables as find_package would.
|
||||
set(ZLIB_INCLUDE_DIRS ${WIN32_ZLIB_PATH})
|
||||
if(POLICY CMP0026)
|
||||
cmake_policy(VERSION 2.8)
|
||||
# The new policy for add_dependencies is to now error if a dependency target
|
||||
# is not found. The old policy didn't care and continued through configuration
|
||||
cmake_policy(SET CMP0026 OLD)
|
||||
endif()
|
||||
get_property(ZLIB_LIBRARIES TARGET ZLIB PROPERTY LOCATION)
|
||||
set(ZLIB_FOUND 1)
|
||||
else()
|
||||
find_package(ZLIB REQUIRED)
|
||||
endif()
|
||||
|
||||
# Make sure ZLib is compiled before the libs.
|
||||
foreach (lib websockets websockets_shared)
|
||||
add_dependencies(${lib} ZLIB)
|
||||
endforeach()
|
||||
|
||||
message(STATUS "ZLib include dirs: ${ZLIB_INCLUDE_DIRS}")
|
||||
message(STATUS "ZLib libraries: ${ZLIB_LIBRARIES}")
|
||||
include_directories(${ZLIB_INCLUDE_DIRS})
|
||||
list(APPEND LIB_LIST ${ZLIB_LIBRARIES})
|
||||
endif(NOT LWS_WITHOUT_EXTENSIONS)
|
||||
|
||||
#
|
||||
# OpenSSL
|
||||
#
|
||||
if (LWS_WITH_SSL)
|
||||
message("Compiling with SSL support")
|
||||
|
||||
if (LWS_USE_CYASSL)
|
||||
# Use CyaSSL as OpenSSL replacement.
|
||||
# TODO: Add a find_package command for this also.
|
||||
message("CyaSSL include dir: ${LWS_CYASSL_INCLUDE_DIRS}")
|
||||
message("CyaSSL libraries: ${LWS_CYASSL_LIB}")
|
||||
|
||||
# Additional to the root directory we need to include
|
||||
# the cyassl/ subdirectory which contains the OpenSSL
|
||||
# compatability layer headers.
|
||||
foreach(inc ${LWS_CYASSL_INCLUDE_DIRS})
|
||||
include_directories("${inc}" "${inc}/cyassl")
|
||||
endforeach()
|
||||
|
||||
list(APPEND LIB_LIST "${LWS_CYASSL_LIB}")
|
||||
else()
|
||||
# TODO: Add support for STATIC also.
|
||||
find_package(OpenSSL REQUIRED)
|
||||
|
||||
message("OpenSSL include dir: ${OPENSSL_INCLUDE_DIR}")
|
||||
message("OpenSSL libraries: ${OPENSSL_LIBRARIES}")
|
||||
|
||||
include_directories("${OPENSSL_INCLUDE_DIR}")
|
||||
list(APPEND LIB_LIST ${OPENSSL_LIBRARIES})
|
||||
|
||||
# Link against dynamic linking functions.
|
||||
# (Don't link directly to libdl since it is not needed on all platforms, it's now a part of libc).
|
||||
list(APPEND LIB_LIST ${CMAKE_DL_LIBS})
|
||||
endif()
|
||||
endif(LWS_WITH_SSL)
|
||||
|
||||
if (LWS_WITH_LIBEV)
|
||||
list(APPEND LIB_LIST "ev")
|
||||
endif(LWS_WITH_LIBEV)
|
||||
|
||||
#
|
||||
# Platform specific libs.
|
||||
#
|
||||
if (WINCE)
|
||||
list(APPEND LIB_LIST ws2.lib)
|
||||
elseif (WIN32)
|
||||
list(APPEND LIB_LIST ws2_32.lib)
|
||||
endif()
|
||||
|
||||
if (UNIX)
|
||||
list(APPEND LIB_LIST m)
|
||||
endif()
|
||||
|
||||
# Setup the linking for all libs.
|
||||
foreach (lib websockets websockets_shared)
|
||||
target_link_libraries(${lib} ${LIB_LIST})
|
||||
endforeach()
|
||||
|
||||
#
|
||||
# Test applications
|
||||
#
|
||||
set(TEST_APP_LIST)
|
||||
if (NOT LWS_WITHOUT_TESTAPPS)
|
||||
#
|
||||
# Helper function for adding a test app.
|
||||
#
|
||||
macro(create_test_app TEST_NAME MAIN_SRC)
|
||||
|
||||
set(TEST_SRCS ${MAIN_SRC})
|
||||
set(TEST_HDR)
|
||||
|
||||
if (WIN32)
|
||||
list(APPEND TEST_SRCS
|
||||
${WIN32_HELPERS_PATH}/getopt.c
|
||||
${WIN32_HELPERS_PATH}/getopt_long.c
|
||||
${WIN32_HELPERS_PATH}/gettimeofday.c
|
||||
)
|
||||
|
||||
list(APPEND TEST_HDR
|
||||
${WIN32_HELPERS_PATH}/getopt.h
|
||||
${WIN32_HELPERS_PATH}/gettimeofday.h
|
||||
)
|
||||
endif(WIN32)
|
||||
|
||||
source_group("Headers Private" FILES ${TEST_HDR})
|
||||
source_group("Sources" FILES ${TEST_SRCS})
|
||||
add_executable(${TEST_NAME} ${TEST_SRCS} ${TEST_HDR})
|
||||
|
||||
if (LWS_LINK_TESTAPPS_DYNAMIC)
|
||||
target_link_libraries(${TEST_NAME} websockets_shared)
|
||||
add_dependencies(${TEST_NAME} websockets_shared)
|
||||
else(LWS_LINK_TESTAPPS_DYNAMIC)
|
||||
target_link_libraries(${TEST_NAME} websockets)
|
||||
add_dependencies(${TEST_NAME} websockets)
|
||||
endif(LWS_LINK_TESTAPPS_DYNAMIC)
|
||||
|
||||
# Set test app specific defines.
|
||||
set_property(TARGET ${TEST_NAME}
|
||||
PROPERTY COMPILE_DEFINITIONS
|
||||
INSTALL_DATADIR="${CMAKE_INSTALL_PREFIX}/share"
|
||||
)
|
||||
|
||||
# Prefix the binary names with libwebsockets.
|
||||
set_target_properties(${TEST_NAME}
|
||||
PROPERTIES
|
||||
OUTPUT_NAME libwebsockets-${TEST_NAME})
|
||||
|
||||
# Add to the list of tests.
|
||||
list(APPEND TEST_APP_LIST ${TEST_NAME})
|
||||
endmacro()
|
||||
|
||||
if (LWS_WITH_SSL AND NOT LWS_USE_CYASSL)
|
||||
message("Searching for OpenSSL executable and dlls")
|
||||
find_package(OpenSSLbins)
|
||||
message("OpenSSL executable: ${OPENSSL_EXECUTABLE}")
|
||||
endif()
|
||||
|
||||
if (NOT LWS_WITHOUT_SERVER)
|
||||
#
|
||||
# test-server
|
||||
#
|
||||
if (NOT LWS_WITHOUT_TEST_SERVER)
|
||||
create_test_app(test-server "test-server/test-server.c")
|
||||
endif()
|
||||
|
||||
#
|
||||
# test-server-extpoll
|
||||
#
|
||||
if (NOT LWS_WITHOUT_TEST_SERVER_EXTPOLL)
|
||||
create_test_app(test-server-extpoll "test-server/test-server.c")
|
||||
# Set defines for this executable only.
|
||||
set_property(
|
||||
TARGET test-server-extpoll
|
||||
PROPERTY COMPILE_DEFINITIONS
|
||||
EXTERNAL_POLL
|
||||
INSTALL_DATADIR="${CMAKE_INSTALL_PREFIX}/share"
|
||||
)
|
||||
|
||||
# We need to link against winsock code.
|
||||
if (WIN32)
|
||||
target_link_libraries(test-server-extpoll ws2_32.lib)
|
||||
endif(WIN32)
|
||||
endif()
|
||||
|
||||
# Data files for running the test server.
|
||||
set(TEST_SERVER_DATA
|
||||
"${PROJECT_SOURCE_DIR}/test-server/favicon.ico"
|
||||
"${PROJECT_SOURCE_DIR}/test-server/leaf.jpg"
|
||||
"${PROJECT_SOURCE_DIR}/test-server/libwebsockets.org-logo.png"
|
||||
"${PROJECT_SOURCE_DIR}/test-server/test.html")
|
||||
|
||||
# Generate self-signed SSL certs for the test-server.
|
||||
if (LWS_WITH_SSL AND OPENSSL_EXECUTABLE AND NOT LWS_WITHOUT_TEST_SERVER)
|
||||
message("Generating SSL Certificates for the test-server...")
|
||||
|
||||
set(TEST_SERVER_SSL_KEY "${PROJECT_BINARY_DIR}/libwebsockets-test-server.key.pem")
|
||||
set(TEST_SERVER_SSL_CERT "${PROJECT_BINARY_DIR}/libwebsockets-test-server.pem")
|
||||
|
||||
if (WIN32)
|
||||
file(WRITE "${PROJECT_BINARY_DIR}/openssl_input.txt"
|
||||
"GB\n"
|
||||
"Erewhon\n"
|
||||
"All around\n"
|
||||
"libwebsockets-test\n"
|
||||
"localhost\n"
|
||||
"none@invalid.org\n\n"
|
||||
)
|
||||
|
||||
# The "type" command is a bit picky with paths.
|
||||
file(TO_NATIVE_PATH "${PROJECT_BINARY_DIR}/openssl_input.txt" OPENSSL_INPUT_WIN_PATH)
|
||||
message("OPENSSL_INPUT_WIN_PATH = ${OPENSSL_INPUT_WIN_PATH}")
|
||||
message("cmd = \"${OPENSSL_EXECUTABLE}\" req -new -newkey rsa:1024 -days 10000 -nodes -x509 -keyout \"${TEST_SERVER_SSL_KEY}\" -out \"${TEST_SERVER_SSL_CERT}\"")
|
||||
|
||||
execute_process(
|
||||
COMMAND cmd /c type "${OPENSSL_INPUT_WIN_PATH}"
|
||||
COMMAND "${OPENSSL_EXECUTABLE}" req -new -newkey rsa:1024 -days 10000 -nodes -x509 -keyout "${TEST_SERVER_SSL_KEY}" -out "${TEST_SERVER_SSL_CERT}"
|
||||
RESULT_VARIABLE OPENSSL_RETURN_CODE)
|
||||
|
||||
message("\n")
|
||||
|
||||
if (OPENSSL_RETURN_CODE)
|
||||
message(WARNING "!!! Failed to generate SSL certificate for Test Server using cmd.exe !!!:\nOpenSSL return code = ${OPENSSL_RETURN_CODE}")
|
||||
else()
|
||||
message("SUCCSESFULLY generated SSL certificate")
|
||||
endif()
|
||||
else()
|
||||
# Unix.
|
||||
execute_process(
|
||||
COMMAND printf "GB\\nErewhon\\nAll around\\nlibwebsockets-test\\n\\nlocalhost\\nnone@invalid.org\\n"
|
||||
COMMAND "${OPENSSL_EXECUTABLE}"
|
||||
req -new -newkey rsa:1024 -days 10000 -nodes -x509 -keyout "${TEST_SERVER_SSL_KEY}" -out "${TEST_SERVER_SSL_CERT}"
|
||||
RESULT_VARIABLE OPENSSL_RETURN_CODE)
|
||||
|
||||
if (OPENSSL_RETURN_CODE)
|
||||
message(WARNING "!!! Failed to generate SSL certificate for Test Server!!!:\nOpenSSL return code = ${OPENSSL_RETURN_CODE}")
|
||||
else()
|
||||
message("SUCCSESFULLY generated SSL certificate")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
list(APPEND TEST_SERVER_DATA
|
||||
"${TEST_SERVER_SSL_KEY}"
|
||||
"${TEST_SERVER_SSL_CERT}")
|
||||
endif()
|
||||
|
||||
add_custom_command(TARGET test-server
|
||||
POST_BUILD
|
||||
COMMAND "${CMAKE_COMMAND}" -E make_directory "$<TARGET_FILE_DIR:test-server>/../share/libwebsockets-test-server")
|
||||
|
||||
# Copy the file needed to run the server so that the test apps can
|
||||
# reach them from their default output location
|
||||
foreach (TEST_FILE ${TEST_SERVER_DATA})
|
||||
if (EXISTS ${TEST_FILE})
|
||||
add_custom_command(TARGET test-server
|
||||
POST_BUILD
|
||||
COMMAND "${CMAKE_COMMAND}" -E copy "${TEST_FILE}" "$<TARGET_FILE_DIR:test-server>/../share/libwebsockets-test-server" VERBATIM)
|
||||
endif()
|
||||
endforeach()
|
||||
endif(NOT LWS_WITHOUT_SERVER)
|
||||
|
||||
if (NOT LWS_WITHOUT_CLIENT)
|
||||
#
|
||||
# test-client
|
||||
#
|
||||
if (NOT LWS_WITHOUT_TEST_CLIENT)
|
||||
create_test_app(test-client "test-server/test-client.c")
|
||||
endif()
|
||||
|
||||
#
|
||||
# test-fraggle
|
||||
#
|
||||
if (NOT LWS_WITHOUT_TEST_FRAGGLE)
|
||||
create_test_app(test-fraggle "test-server/test-fraggle.c")
|
||||
endif()
|
||||
|
||||
#
|
||||
# test-ping
|
||||
#
|
||||
if (NOT LWS_WITHOUT_TEST_PING)
|
||||
create_test_app(test-ping "test-server/test-ping.c")
|
||||
endif()
|
||||
#
|
||||
# test-echo
|
||||
#
|
||||
if (NOT WITHOUT_TEST_ECHO)
|
||||
create_test_app(test-echo "test-server/test-echo.c")
|
||||
endif()
|
||||
|
||||
endif(NOT LWS_WITHOUT_CLIENT)
|
||||
|
||||
#
|
||||
# Copy OpenSSL dlls to the output directory on Windows.
|
||||
# (Otherwise we'll get an error when trying to run)
|
||||
#
|
||||
if (WIN32 AND LWS_WITH_SSL AND NOT LWS_USE_CYASSL)
|
||||
if(OPENSSL_BIN_FOUND)
|
||||
message("OpenSSL dlls found:")
|
||||
message(" Libeay: ${LIBEAY_BIN}")
|
||||
message(" SSLeay: ${SSLEAY_BIN}")
|
||||
|
||||
foreach(TARGET_BIN ${TEST_APP_LIST})
|
||||
add_custom_command(TARGET ${TARGET_BIN}
|
||||
POST_BUILD
|
||||
COMMAND "${CMAKE_COMMAND}" -E copy "${LIBEAY_BIN}" "$<TARGET_FILE_DIR:${TARGET_BIN}>" VERBATIM)
|
||||
|
||||
add_custom_command(TARGET ${TARGET_BIN}
|
||||
POST_BUILD
|
||||
COMMAND "${CMAKE_COMMAND}" -E copy "${SSLEAY_BIN}" "$<TARGET_FILE_DIR:${TARGET_BIN}>" VERBATIM)
|
||||
endforeach()
|
||||
endif()
|
||||
endif()
|
||||
endif(NOT LWS_WITHOUT_TESTAPPS)
|
||||
|
||||
if (UNIX)
|
||||
# Generate documentation.
|
||||
# TODO: Fix this on Windows.
|
||||
message("Generating API documentation")
|
||||
file(GLOB C_FILES "${PROJECT_SOURCE_DIR}/lib/*.c")
|
||||
execute_process(COMMAND "${CMAKE_COMMAND}" -E make_directory "${PROJECT_BINARY_DIR}/doc/")
|
||||
|
||||
execute_process(
|
||||
COMMAND "${PROJECT_SOURCE_DIR}/scripts/kernel-doc" -html ${C_FILES} ${HDR_PUBLIC}
|
||||
OUTPUT_FILE "${PROJECT_BINARY_DIR}/doc/libwebsockets-api-doc.html"
|
||||
ERROR_QUIET)
|
||||
|
||||
execute_process(
|
||||
COMMAND "${PROJECT_SOURCE_DIR}/scripts/kernel-doc" -text ${C_FILES} ${HDR_PUBLIC}
|
||||
OUTPUT_FILE "${PROJECT_BINARY_DIR}/doc/libwebsockets-api-doc.txt"
|
||||
ERROR_QUIET)
|
||||
|
||||
# Generate and install pkgconfig.
|
||||
# (This is not indented, because the tabs will be part of the output)
|
||||
file(WRITE "${PROJECT_BINARY_DIR}/libwebsockets.pc"
|
||||
"prefix=\"${CMAKE_INSTALL_PREFIX}\"
|
||||
exec_prefix=\${prefix}
|
||||
libdir=\${exec_prefix}/lib${LIB_SUFFIX}
|
||||
includedir=\${prefix}/include
|
||||
|
||||
Name: libwebsockets
|
||||
Description: Websockets server and client library
|
||||
Version: ${CPACK_PACKAGE_VERSION_MAJOR}.${CPACK_PACKAGE_VERSION_MINOR}
|
||||
|
||||
Libs: -L\${libdir} -lwebsockets
|
||||
Cflags: -I\${includedir}"
|
||||
)
|
||||
|
||||
install(FILES "${PROJECT_BINARY_DIR}/libwebsockets.pc"
|
||||
DESTINATION lib${LIB_SUFFIX}/pkgconfig)
|
||||
endif(UNIX)
|
||||
|
||||
#
|
||||
# Installation preparations.
|
||||
#
|
||||
|
||||
if(WIN32 AND NOT CYGWIN)
|
||||
set(DEF_INSTALL_CMAKE_DIR cmake)
|
||||
else()
|
||||
set(DEF_INSTALL_CMAKE_DIR lib/cmake/libwebsockets)
|
||||
endif()
|
||||
|
||||
set(LWS_INSTALL_CMAKE_DIR ${DEF_INSTALL_CMAKE_DIR} CACHE PATH "Installation directory for CMake files")
|
||||
|
||||
# Export targets (This is used for other CMake projects to easily find the libraries and include files).
|
||||
export(TARGETS websockets websockets_shared
|
||||
FILE "${PROJECT_BINARY_DIR}/LibwebsocketsTargets.cmake")
|
||||
export(PACKAGE libwebsockets)
|
||||
|
||||
# Generate the config file for the build-tree.
|
||||
set(LWS__INCLUDE_DIRS
|
||||
"${PROJECT_SOURCE_DIR}/lib"
|
||||
"${PROJECT_BINARY_DIR}")
|
||||
set(LIBWEBSOCKETS_INCLUDE_DIRS ${LWS__INCLUDE_DIRS} CACHE PATH "Libwebsockets include directories")
|
||||
configure_file(${PROJECT_SOURCE_DIR}/cmake/LibwebsocketsConfig.cmake.in
|
||||
${PROJECT_BINARY_DIR}/LibwebsocketsConfig.cmake
|
||||
@ONLY)
|
||||
|
||||
# Generate the config file for the installation tree.
|
||||
get_filename_component(LWS_ABSOLUTE_INSTALL_CMAKE_DIR ${LWS_INSTALL_CMAKE_DIR} ABSOLUTE)
|
||||
get_filename_component(LWS_ABSOLUTE_INSTALL_INCLUDE_DIR ${LWS_INSTALL_INCLUDE_DIR} ABSOLUTE)
|
||||
file(RELATIVE_PATH
|
||||
REL_INCLUDE_DIR
|
||||
"${LWS_ABSOLUTE_INSTALL_CMAKE_DIR}"
|
||||
"${LWS_ABSOLUTE_INSTALL_INCLUDE_DIR}") # Calculate the relative directory from the cmake dir.
|
||||
|
||||
# Note the EVENT_CMAKE_DIR is defined in JanssonConfig.cmake.in,
|
||||
# we escape it here so it's evaluated when it is included instead
|
||||
# so that the include dirs are given relative to where the
|
||||
# config file is located.
|
||||
set(LWS__INCLUDE_DIRS
|
||||
"\${LWS_CMAKE_DIR}/${REL_INCLUDE_DIR}")
|
||||
configure_file(${PROJECT_SOURCE_DIR}/cmake/LibwebsocketsConfig.cmake.in
|
||||
${PROJECT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/LibwebsocketsConfig.cmake
|
||||
@ONLY)
|
||||
|
||||
# Generate version info for both build-tree and install-tree.
|
||||
configure_file(${PROJECT_SOURCE_DIR}/cmake/LibwebsocketsConfigVersion.cmake.in
|
||||
${PROJECT_BINARY_DIR}/LibwebsocketsConfigVersion.cmake
|
||||
@ONLY)
|
||||
|
||||
set_target_properties(websockets websockets_shared
|
||||
PROPERTIES PUBLIC_HEADER "${HDR_PUBLIC}")
|
||||
|
||||
#
|
||||
# Installation.
|
||||
#
|
||||
|
||||
# Install libs and headers.
|
||||
install(TARGETS websockets websockets_shared
|
||||
EXPORT LibwebsocketsTargets
|
||||
LIBRARY DESTINATION "${LWS_INSTALL_LIB_DIR}${LIB_SUFFIX}" COMPONENT libraries
|
||||
ARCHIVE DESTINATION "${LWS_INSTALL_LIB_DIR}${LIB_SUFFIX}" COMPONENT libraries
|
||||
RUNTIME DESTINATION "${LWS_INSTALL_BIN_DIR}" COMPONENT libraries # Windows DLLs
|
||||
PUBLIC_HEADER DESTINATION "${LWS_INSTALL_INCLUDE_DIR}" COMPONENT dev)
|
||||
set(CPACK_COMPONENT_LIBRARIES_DISPLAY_NAME "Libraries")
|
||||
set(CPACK_COMPONENT_DEV_DISPLAY_NAME "Development files")
|
||||
|
||||
# Install test apps.
|
||||
if (NOT LWS_WITHOUT_TESTAPPS AND NOT LWS_WITHOUT_CLIENT)
|
||||
install(TARGETS test-client ${TEST_APP_LIST}
|
||||
RUNTIME DESTINATION ${LWS_INSTALL_EXAMPLES_DIR}
|
||||
COMPONENT examples)
|
||||
set(CPACK_COMPONENT_EXAMPLES_DISPLAY_NAME "Example files")
|
||||
endif()
|
||||
|
||||
# Programs shared files used by the test-server.
|
||||
if (NOT LWS_WITHOUT_TESTAPPS AND NOT LWS_WITHOUT_SERVER)
|
||||
install(FILES ${TEST_SERVER_DATA}
|
||||
DESTINATION share/libwebsockets-test-server
|
||||
COMPONENT examples)
|
||||
endif()
|
||||
|
||||
# Install exports for the install-tree.
|
||||
install(EXPORT LibwebsocketsTargets
|
||||
DESTINATION "${LWS_INSTALL_CMAKE_DIR}" COMPONENT dev)
|
||||
|
||||
# build subdir is not part of sources
|
||||
set(CPACK_SOURCE_IGNORE_FILES $(CPACK_SOURCE_IGNORE_FILES) ".git" "build" "tgz" "tar.gz")
|
||||
|
||||
# Most people are more used to "make dist" compared to "make package_source"
|
||||
add_custom_target(dist COMMAND "${CMAKE_MAKE_PROGRAM}" package_source)
|
||||
|
||||
include(UseRPMTools)
|
||||
if (RPMTools_FOUND)
|
||||
RPMTools_ADD_RPM_TARGETS(libwebsockets libwebsockets.spec)
|
||||
endif()
|
||||
|
||||
message("---------------------------------------------------------------------")
|
||||
message(" Settings: (For more help do cmake -LH <srcpath>")
|
||||
message("---------------------------------------------------------------------")
|
||||
message(" LWS_WITH_SSL = ${LWS_WITH_SSL} (SSL Support)")
|
||||
message(" LWS_SSL_CLIENT_USE_OS_CA_CERTS = ${LWS_SSL_CLIENT_USE_OS_CA_CERTS}")
|
||||
message(" LWS_USE_CYASSL = ${LWS_USE_CYASSL} (CyaSSL replacement for OpenSSL)")
|
||||
if (LWS_USE_CYASSL)
|
||||
message(" LWS_CYASSL_LIB = ${LWS_CYASSL_LIB}")
|
||||
message(" LWS_CYASSL_INCLUDE_DIRS = ${LWS_CYASSL_INCLUDE_DIRS}")
|
||||
endif()
|
||||
message(" LWS_WITHOUT_BUILTIN_GETIFADDRS = ${LWS_WITHOUT_BUILTIN_GETIFADDRS}")
|
||||
message(" LWS_WITHOUT_CLIENT = ${LWS_WITHOUT_CLIENT}")
|
||||
message(" LWS_WITHOUT_SERVER = ${LWS_WITHOUT_SERVER}")
|
||||
message(" LWS_LINK_TESTAPPS_DYNAMIC = ${LWS_LINK_TESTAPPS_DYNAMIC}")
|
||||
message(" LWS_WITHOUT_TESTAPPS = ${LWS_WITHOUT_TESTAPPS}")
|
||||
message(" LWS_WITHOUT_TEST_SERVER = ${LWS_WITHOUT_TEST_SERVER}")
|
||||
message(" LWS_WITHOUT_TEST_SERVER_EXTPOLL = ${LWS_WITHOUT_TEST_SERVER_EXTPOLL}")
|
||||
message(" LWS_WITHOUT_TEST_PING = ${LWS_WITHOUT_TEST_PING}")
|
||||
message(" LWS_WITHOUT_TEST_CLIENT = ${LWS_WITHOUT_TEST_CLIENT}")
|
||||
message(" LWS_WITHOUT_TEST_FRAGGLE = ${LWS_WITHOUT_TEST_FRAGGLE}")
|
||||
message(" LWS_WITHOUT_DEBUG = ${LWS_WITHOUT_DEBUG}")
|
||||
message(" LWS_WITHOUT_EXTENSIONS = ${LWS_WITHOUT_EXTENSIONS}")
|
||||
message(" LWS_WITH_LATENCY = ${LWS_WITH_LATENCY}")
|
||||
message(" LWS_WITHOUT_DAEMONIZE = ${LWS_WITHOUT_DAEMONIZE}")
|
||||
message(" LWS_USE_LIBEV = ${LWS_USE_LIBEV}")
|
||||
message(" LWS_IPV6 = ${LWS_IPV6}")
|
||||
message(" LWS_WITH_HTTP2 = ${LWS_WITH_HTTP2}")
|
||||
message("---------------------------------------------------------------------")
|
||||
|
||||
# These will be available to parent projects including libwebsockets using add_subdirectory()
|
||||
set(LIBWEBSOCKETS_LIBRARIES websocket websockets_shared CACHE STRING "Libwebsocket libraries")
|
||||
set(LIBWEBSOCKETS_LIBRARIES_STATIC websocket CACHE STRING "Libwebsocket static library")
|
||||
set(LIBWEBSOCKETS_LIBRARIES_SHARED websockets_shared CACHE STRING "Libwebsocket shared library")
|
||||
|
||||
# This must always be last!
|
||||
include(CPack)
|
||||
Vendored
+526
@@ -0,0 +1,526 @@
|
||||
Libwebsockets and included programs are provided under the terms of the GNU
|
||||
Library General Public License (LGPL) 2.1, with the following exceptions:
|
||||
|
||||
1) Static linking of programs with the libwebsockets library does not
|
||||
constitute a derivative work and does not require the author to provide
|
||||
source code for the program, use the shared libwebsockets libraries, or
|
||||
link their program against a user-supplied version of libwebsockets.
|
||||
|
||||
If you link the program to a modified version of libwebsockets, then the
|
||||
changes to libwebsockets must be provided under the terms of the LGPL in
|
||||
sections 1, 2, and 4.
|
||||
|
||||
2) You do not have to provide a copy of the libwebsockets license with
|
||||
programs that are linked to the libwebsockets library, nor do you have to
|
||||
identify the libwebsockets license in your program or documentation as
|
||||
required by section 6 of the LGPL.
|
||||
|
||||
However, programs must still identify their use of libwebsockets. The
|
||||
following example statement can be included in user documentation to
|
||||
satisfy this requirement:
|
||||
|
||||
"[program] is based in part on the work of the libwebsockets project
|
||||
(http://libwebsockets.org)"
|
||||
|
||||
GNU LESSER GENERAL PUBLIC LICENSE
|
||||
Version 2.1, February 1999
|
||||
|
||||
Copyright (C) 1991, 1999 Free Software Foundation, Inc.
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
[This is the first released version of the Lesser GPL. It also counts
|
||||
as the successor of the GNU Library Public License, version 2, hence
|
||||
the version number 2.1.]
|
||||
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
Licenses are intended to guarantee your freedom to share and change
|
||||
free software--to make sure the software is free for all its users.
|
||||
|
||||
This license, the Lesser General Public License, applies to some
|
||||
specially designated software packages--typically libraries--of the
|
||||
Free Software Foundation and other authors who decide to use it. You
|
||||
can use it too, but we suggest you first think carefully about whether
|
||||
this license or the ordinary General Public License is the better
|
||||
strategy to use in any particular case, based on the explanations below.
|
||||
|
||||
When we speak of free software, we are referring to freedom of use,
|
||||
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 and use pieces of
|
||||
it in new free programs; and that you are informed that you can do
|
||||
these things.
|
||||
|
||||
To protect your rights, we need to make restrictions that forbid
|
||||
distributors to deny you these rights or to ask you to surrender these
|
||||
rights. These restrictions translate to certain responsibilities for
|
||||
you if you distribute copies of the library or if you modify it.
|
||||
|
||||
For example, if you distribute copies of the library, whether gratis
|
||||
or for a fee, you must give the recipients all the rights that we gave
|
||||
you. You must make sure that they, too, receive or can get the source
|
||||
code. If you link other code with the library, you must provide
|
||||
complete object files to the recipients, so that they can relink them
|
||||
with the library after making changes to the library and recompiling
|
||||
it. And you must show them these terms so they know their rights.
|
||||
|
||||
We protect your rights with a two-step method: (1) we copyright the
|
||||
library, and (2) we offer you this license, which gives you legal
|
||||
permission to copy, distribute and/or modify the library.
|
||||
|
||||
To protect each distributor, we want to make it very clear that
|
||||
there is no warranty for the free library. Also, if the library is
|
||||
modified by someone else and passed on, the recipients should know
|
||||
that what they have is not the original version, so that the original
|
||||
author's reputation will not be affected by problems that might be
|
||||
introduced by others.
|
||||
|
||||
Finally, software patents pose a constant threat to the existence of
|
||||
any free program. We wish to make sure that a company cannot
|
||||
effectively restrict the users of a free program by obtaining a
|
||||
restrictive license from a patent holder. Therefore, we insist that
|
||||
any patent license obtained for a version of the library must be
|
||||
consistent with the full freedom of use specified in this license.
|
||||
|
||||
Most GNU software, including some libraries, is covered by the
|
||||
ordinary GNU General Public License. This license, the GNU Lesser
|
||||
General Public License, applies to certain designated libraries, and
|
||||
is quite different from the ordinary General Public License. We use
|
||||
this license for certain libraries in order to permit linking those
|
||||
libraries into non-free programs.
|
||||
|
||||
When a program is linked with a library, whether statically or using
|
||||
a shared library, the combination of the two is legally speaking a
|
||||
combined work, a derivative of the original library. The ordinary
|
||||
General Public License therefore permits such linking only if the
|
||||
entire combination fits its criteria of freedom. The Lesser General
|
||||
Public License permits more lax criteria for linking other code with
|
||||
the library.
|
||||
|
||||
We call this license the "Lesser" General Public License because it
|
||||
does Less to protect the user's freedom than the ordinary General
|
||||
Public License. It also provides other free software developers Less
|
||||
of an advantage over competing non-free programs. These disadvantages
|
||||
are the reason we use the ordinary General Public License for many
|
||||
libraries. However, the Lesser license provides advantages in certain
|
||||
special circumstances.
|
||||
|
||||
For example, on rare occasions, there may be a special need to
|
||||
encourage the widest possible use of a certain library, so that it becomes
|
||||
a de-facto standard. To achieve this, non-free programs must be
|
||||
allowed to use the library. A more frequent case is that a free
|
||||
library does the same job as widely used non-free libraries. In this
|
||||
case, there is little to gain by limiting the free library to free
|
||||
software only, so we use the Lesser General Public License.
|
||||
|
||||
In other cases, permission to use a particular library in non-free
|
||||
programs enables a greater number of people to use a large body of
|
||||
free software. For example, permission to use the GNU C Library in
|
||||
non-free programs enables many more people to use the whole GNU
|
||||
operating system, as well as its variant, the GNU/Linux operating
|
||||
system.
|
||||
|
||||
Although the Lesser General Public License is Less protective of the
|
||||
users' freedom, it does ensure that the user of a program that is
|
||||
linked with the Library has the freedom and the wherewithal to run
|
||||
that program using a modified version of the Library.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow. Pay close attention to the difference between a
|
||||
"work based on the library" and a "work that uses the library". The
|
||||
former contains code derived from the library, whereas the latter must
|
||||
be combined with the library in order to run.
|
||||
|
||||
GNU LESSER GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License Agreement applies to any software library or other
|
||||
program which contains a notice placed by the copyright holder or
|
||||
other authorized party saying it may be distributed under the terms of
|
||||
this Lesser General Public License (also called "this License").
|
||||
Each licensee is addressed as "you".
|
||||
|
||||
A "library" means a collection of software functions and/or data
|
||||
prepared so as to be conveniently linked with application programs
|
||||
(which use some of those functions and data) to form executables.
|
||||
|
||||
The "Library", below, refers to any such software library or work
|
||||
which has been distributed under these terms. A "work based on the
|
||||
Library" means either the Library or any derivative work under
|
||||
copyright law: that is to say, a work containing the Library or a
|
||||
portion of it, either verbatim or with modifications and/or translated
|
||||
straightforwardly into another language. (Hereinafter, translation is
|
||||
included without limitation in the term "modification".)
|
||||
|
||||
"Source code" for a work means the preferred form of the work for
|
||||
making modifications to it. For a library, 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 library.
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running a program using the Library is not restricted, and output from
|
||||
such a program is covered only if its contents constitute a work based
|
||||
on the Library (independent of the use of the Library in a tool for
|
||||
writing it). Whether that is true depends on what the Library does
|
||||
and what the program that uses the Library does.
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Library's
|
||||
complete 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 distribute a copy of this License along with the
|
||||
Library.
|
||||
|
||||
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 Library or any portion
|
||||
of it, thus forming a work based on the Library, 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) The modified work must itself be a software library.
|
||||
|
||||
b) You must cause the files modified to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
|
||||
c) You must cause the whole of the work to be licensed at no
|
||||
charge to all third parties under the terms of this License.
|
||||
|
||||
d) If a facility in the modified Library refers to a function or a
|
||||
table of data to be supplied by an application program that uses
|
||||
the facility, other than as an argument passed when the facility
|
||||
is invoked, then you must make a good faith effort to ensure that,
|
||||
in the event an application does not supply such function or
|
||||
table, the facility still operates, and performs whatever part of
|
||||
its purpose remains meaningful.
|
||||
|
||||
(For example, a function in a library to compute square roots has
|
||||
a purpose that is entirely well-defined independent of the
|
||||
application. Therefore, Subsection 2d requires that any
|
||||
application-supplied function or table used by this function must
|
||||
be optional: if the application does not supply it, the square
|
||||
root function must still compute square roots.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Library,
|
||||
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 Library, 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 Library.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Library
|
||||
with the Library (or with a work based on the Library) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
|
||||
3. You may opt to apply the terms of the ordinary GNU General Public
|
||||
License instead of this License to a given copy of the Library. To do
|
||||
this, you must alter all the notices that refer to this License, so
|
||||
that they refer to the ordinary GNU General Public License, version 2,
|
||||
instead of to this License. (If a newer version than version 2 of the
|
||||
ordinary GNU General Public License has appeared, then you can specify
|
||||
that version instead if you wish.) Do not make any other change in
|
||||
these notices.
|
||||
|
||||
Once this change is made in a given copy, it is irreversible for
|
||||
that copy, so the ordinary GNU General Public License applies to all
|
||||
subsequent copies and derivative works made from that copy.
|
||||
|
||||
This option is useful when you wish to copy part of the code of
|
||||
the Library into a program that is not a library.
|
||||
|
||||
4. You may copy and distribute the Library (or a portion or
|
||||
derivative of it, under Section 2) in object code or executable form
|
||||
under the terms of Sections 1 and 2 above provided that you 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.
|
||||
|
||||
If distribution of 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 satisfies the requirement to
|
||||
distribute the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
5. A program that contains no derivative of any portion of the
|
||||
Library, but is designed to work with the Library by being compiled or
|
||||
linked with it, is called a "work that uses the Library". Such a
|
||||
work, in isolation, is not a derivative work of the Library, and
|
||||
therefore falls outside the scope of this License.
|
||||
|
||||
However, linking a "work that uses the Library" with the Library
|
||||
creates an executable that is a derivative of the Library (because it
|
||||
contains portions of the Library), rather than a "work that uses the
|
||||
library". The executable is therefore covered by this License.
|
||||
Section 6 states terms for distribution of such executables.
|
||||
|
||||
When a "work that uses the Library" uses material from a header file
|
||||
that is part of the Library, the object code for the work may be a
|
||||
derivative work of the Library even though the source code is not.
|
||||
Whether this is true is especially significant if the work can be
|
||||
linked without the Library, or if the work is itself a library. The
|
||||
threshold for this to be true is not precisely defined by law.
|
||||
|
||||
If such an object file uses only numerical parameters, data
|
||||
structure layouts and accessors, and small macros and small inline
|
||||
functions (ten lines or less in length), then the use of the object
|
||||
file is unrestricted, regardless of whether it is legally a derivative
|
||||
work. (Executables containing this object code plus portions of the
|
||||
Library will still fall under Section 6.)
|
||||
|
||||
Otherwise, if the work is a derivative of the Library, you may
|
||||
distribute the object code for the work under the terms of Section 6.
|
||||
Any executables containing that work also fall under Section 6,
|
||||
whether or not they are linked directly with the Library itself.
|
||||
|
||||
6. As an exception to the Sections above, you may also combine or
|
||||
link a "work that uses the Library" with the Library to produce a
|
||||
work containing portions of the Library, and distribute that work
|
||||
under terms of your choice, provided that the terms permit
|
||||
modification of the work for the customer's own use and reverse
|
||||
engineering for debugging such modifications.
|
||||
|
||||
You must give prominent notice with each copy of the work that the
|
||||
Library is used in it and that the Library and its use are covered by
|
||||
this License. You must supply a copy of this License. If the work
|
||||
during execution displays copyright notices, you must include the
|
||||
copyright notice for the Library among them, as well as a reference
|
||||
directing the user to the copy of this License. Also, you must do one
|
||||
of these things:
|
||||
|
||||
a) Accompany the work with the complete corresponding
|
||||
machine-readable source code for the Library including whatever
|
||||
changes were used in the work (which must be distributed under
|
||||
Sections 1 and 2 above); and, if the work is an executable linked
|
||||
with the Library, with the complete machine-readable "work that
|
||||
uses the Library", as object code and/or source code, so that the
|
||||
user can modify the Library and then relink to produce a modified
|
||||
executable containing the modified Library. (It is understood
|
||||
that the user who changes the contents of definitions files in the
|
||||
Library will not necessarily be able to recompile the application
|
||||
to use the modified definitions.)
|
||||
|
||||
b) Use a suitable shared library mechanism for linking with the
|
||||
Library. A suitable mechanism is one that (1) uses at run time a
|
||||
copy of the library already present on the user's computer system,
|
||||
rather than copying library functions into the executable, and (2)
|
||||
will operate properly with a modified version of the library, if
|
||||
the user installs one, as long as the modified version is
|
||||
interface-compatible with the version that the work was made with.
|
||||
|
||||
c) Accompany the work with a written offer, valid for at
|
||||
least three years, to give the same user the materials
|
||||
specified in Subsection 6a, above, for a charge no more
|
||||
than the cost of performing this distribution.
|
||||
|
||||
d) If distribution of the work is made by offering access to copy
|
||||
from a designated place, offer equivalent access to copy the above
|
||||
specified materials from the same place.
|
||||
|
||||
e) Verify that the user has already received a copy of these
|
||||
materials or that you have already sent this user a copy.
|
||||
|
||||
For an executable, the required form of the "work that uses the
|
||||
Library" must include any data and utility programs needed for
|
||||
reproducing the executable from it. However, as a special exception,
|
||||
the materials to be 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.
|
||||
|
||||
It may happen that this requirement contradicts the license
|
||||
restrictions of other proprietary libraries that do not normally
|
||||
accompany the operating system. Such a contradiction means you cannot
|
||||
use both them and the Library together in an executable that you
|
||||
distribute.
|
||||
|
||||
7. You may place library facilities that are a work based on the
|
||||
Library side-by-side in a single library together with other library
|
||||
facilities not covered by this License, and distribute such a combined
|
||||
library, provided that the separate distribution of the work based on
|
||||
the Library and of the other library facilities is otherwise
|
||||
permitted, and provided that you do these two things:
|
||||
|
||||
a) Accompany the combined library with a copy of the same work
|
||||
based on the Library, uncombined with any other library
|
||||
facilities. This must be distributed under the terms of the
|
||||
Sections above.
|
||||
|
||||
b) Give prominent notice with the combined library of the fact
|
||||
that part of it is a work based on the Library, and explaining
|
||||
where to find the accompanying uncombined form of the same work.
|
||||
|
||||
8. You may not copy, modify, sublicense, link with, or distribute
|
||||
the Library except as expressly provided under this License. Any
|
||||
attempt otherwise to copy, modify, sublicense, link with, or
|
||||
distribute the Library 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.
|
||||
|
||||
9. 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 Library or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Library (or any work based on the
|
||||
Library), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Library or works based on it.
|
||||
|
||||
10. Each time you redistribute the Library (or any work based on the
|
||||
Library), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute, link with or modify the Library
|
||||
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 with
|
||||
this License.
|
||||
|
||||
11. 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 Library at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Library 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 Library.
|
||||
|
||||
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.
|
||||
|
||||
12. If the distribution and/or use of the Library is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Library 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.
|
||||
|
||||
13. The Free Software Foundation may publish revised and/or new
|
||||
versions of the Lesser 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 Library
|
||||
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 Library does not specify a
|
||||
license version number, you may choose any version ever published by
|
||||
the Free Software Foundation.
|
||||
|
||||
14. If you wish to incorporate parts of the Library into other free
|
||||
programs whose distribution conditions are incompatible with these,
|
||||
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
|
||||
|
||||
15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
|
||||
WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
|
||||
EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
|
||||
OTHER PARTIES PROVIDE THE LIBRARY "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
|
||||
LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
|
||||
THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
||||
|
||||
16. 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 LIBRARY 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
|
||||
LIBRARY (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 LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), 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 Libraries
|
||||
|
||||
If you develop a new library, and you want it to be of the greatest
|
||||
possible use to the public, we recommend making it free software that
|
||||
everyone can redistribute and change. You can do so by permitting
|
||||
redistribution under these terms (or, alternatively, under the terms of the
|
||||
ordinary General Public License).
|
||||
|
||||
To apply these terms, attach the following notices to the library. 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.
|
||||
|
||||
<one line to give the library's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
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 Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or your
|
||||
school, if any, to sign a "copyright disclaimer" for the library, if
|
||||
necessary. Here is a sample; alter the names:
|
||||
|
||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the
|
||||
library `Frob' (a library for tweaking knobs) written by James Random Hacker.
|
||||
|
||||
<signature of Ty Coon>, 1 April 1990
|
||||
Ty Coon, President of Vice
|
||||
|
||||
That's all there is to it!
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user