Compare commits

..

286 Commits

Author SHA1 Message Date
KimLS a68d638760 Missing float.h 2016-09-12 20:02:46 -07:00
KimLS e5620f6d98 GCC not like & iter here 2016-09-12 19:56:03 -07:00
KimLS 59df65fa21 GCC compile fixes 2016-09-12 19:48:48 -07:00
KimLS 3469af6777 Remove common acting as an inc dir, VS loves it, GCC hates it. 2016-09-12 00:01:20 -07:00
KimLS 2fd439dd0b Revert "Remove format lib all together it was a relic of spdlog anyway"
This reverts commit 487dccfddd.
2016-09-11 21:43:42 -07:00
KimLS 487dccfddd Remove format lib all together it was a relic of spdlog anyway 2016-09-11 21:31:36 -07:00
KimLS 7a9b07871e More missing functions, wish our base version of cmake was higher now... 2016-09-11 19:07:30 -07:00
KimLS 9328ba32d8 Oops 2016-09-11 19:02:02 -07:00
KimLS c08d5b1676 Hopefully can actually be run by base cmake now 2016-09-11 18:59:14 -07:00
KimLS b50c85d086 Reduced initial daybreak ping, some work on what needs to be done to support the first major patch (very little), CMakeLists.txt changes 2016-09-11 18:35:37 -07:00
KimLS 8a73f50601 Merge branch 'master' into event_loop 2016-09-10 22:19:39 -07:00
KimLS 16a96a2756 UCS basically works now, really needs to be rewritten. 2016-09-10 22:18:52 -07:00
Natedog2012 d260bb5cd4 Merge pull request #554 from KinglyKrab/master
Added support for server-wide marquee messages.
2016-09-10 10:10:18 -07:00
KimLS 4bbc22cc24 Proof of concept daybreak implementation using login 2016-09-10 00:01:37 -07:00
Kinglykrab 4816c1fc9a Added support for server-wide marquee messages. 2016-09-09 23:59:23 -04:00
Michael Cook (mackal) 50469b858b Merge pull request #553 from KinglyKrab/master
Added GetAAPercent() to Perl and Lua.
2016-09-08 22:08:47 -04:00
Kinglykrab 64998a398d Added GetAAPercent() to Perl and Lua. 2016-09-08 21:59:15 -04:00
Akkadius 9a3af63f65 Update readme [skip ci] 2016-09-07 15:10:16 -05:00
Akkadius 5679f45f5b Update readme [skip ci] 2016-09-07 12:45:14 -05:00
Akkadius 66c0da85e6 Take out Linux source build from the install.sh file since eqemu_server.pl is flexibly taking care of it 2016-09-06 22:51:29 -05:00
Akkadius 4246e4f79b Fix linux installs when in new_server routine [skip ci] 2016-09-06 22:44:37 -05:00
Akkadius 90dc7a4e38 Fix linux installs [skip ci] 2016-09-06 22:36:50 -05:00
Akkadius bf28354301 Upload Linux installer for Debian/Ubuntu/CentOS/Fedora utils/scripts/linux_installer/install.sh [skip ci] 2016-09-06 22:14:14 -05:00
Akkadius 5f1141dfb1 eqemu_server.pl - Auto update bots database on world bootup if bots enabled [skip ci] 2016-09-06 22:04:38 -05:00
Akkadius 5b03fba463 Update eqemu_server.pl - Fix windows installs [skip ci] 2016-09-06 20:04:21 -05:00
Akkadius 0efd0c5f73 Update eqemu_server.pl [skip ci] 2016-09-05 15:26:12 -05:00
Akkadius 2947e3f39f Update eqemu_server.pl [skip ci] 2016-09-05 02:33:18 -05:00
Akkadius 77974c83d7 Update eqemu_server.pl [skip ci] 2016-09-05 02:31:28 -05:00
KimLS b62cc3b6fa Daybreak connection classes 2016-09-04 19:56:30 -07:00
Michael Cook (mackal) d0bb3047f0 Let's fix the fear pathing flags right away after SE_ImmuneFleeing
This speeds up the response to spells like Call of Challenge
Before it would fix the flags the next tick, which makes the spell
mostly useless
2016-09-04 20:59:39 -04:00
KimLS 9597101f08 Event loop basics + libuv 2016-09-03 22:04:25 -07:00
Michael Cook (mackal) 739b1bfaa3 Fix target buffs showing PC songs 2016-09-03 21:54:59 -04:00
Uleat fb308eaa01 Rule-based update to 'Bind Wound' behavior 2016-09-03 17:08:48 -04:00
Michael Cook (mackal) 7c40bcff53 Fix enrage for NPC classes that can't ripo 2016-09-02 18:16:09 -04:00
Akkadius ec87656d58 Add rule Spells:NPCInnateProcOverride, defaults to true 2016-09-01 01:05:06 -05:00
Uleat 159ba9f487 Fix for BotDatabase::SaveEquipmentColor crash 2016-08-31 23:02:16 -04:00
Michael Cook (mackal) d8fe5124ff Fix some spell set loading issues 2016-08-29 19:23:40 -04:00
Michael Cook (mackal) fa337d441e Use StopCasting when we send SPELL_RECAST error 2016-08-29 14:08:22 -04:00
Michael Cook (mackal) ea1ae1a0a4 Use StopCasting instead of Interrupt on SpellFinished failure
Most of these failures already show a message, live doesn't double
up on failure message + interrupt message, so lets not

There are a few logic error returns, but those really shouldn't happen
2016-08-29 13:27:42 -04:00
Michael Cook (mackal) 95ea61114a Merge pull request #551 from N0ctrnl/patch-1
Added rule to allow MQ2 targeting without filling up the hackers table
2016-08-28 17:34:19 -04:00
Kurt Gilpin 585e5830f7 Update client_packet.cpp 2016-08-28 12:23:59 -05:00
Kurt Gilpin bfb77803d8 Update client_packet.cpp 2016-08-28 07:03:00 -05:00
Kurt Gilpin 364ab42c49 Add rule to ignore MQ2 targeting 2016-08-28 07:00:20 -05:00
Michael Cook (mackal) 89183cf8b7 clang-format LoadZoneObjects 2016-08-27 22:26:44 -04:00
Michael Cook (mackal) aaa116d97c Add support for object display names
Ex. Kejek Forge in Stonebrunt Mountains
2016-08-27 22:24:08 -04:00
Michael Cook (mackal) 4360021fc9 Merge pull request #550 from KinglyKrab/master
World:EnableIPExemptions should be false by default. (Woops.)
2016-08-27 21:45:17 -04:00
Kinglykrab b7b233d46f World:EnableIPExemptions should be false by default. (Woops.) 2016-08-27 21:44:04 -04:00
Akkadius 5c43f2d80e Merge pull request #549 from KinglyKrab/master
Fixed quantity in merchant purchase.
2016-08-27 16:59:58 -05:00
Kinglykrab ed9b6db369 Added optional IP-based account exemptions. 2016-08-27 17:49:04 -04:00
Akkadius dd0d15e134 More testing [skip ci] 2016-08-27 03:20:22 -05:00
Akkadius 29d6817019 More testing [skip ci] 2016-08-27 03:19:33 -05:00
Akkadius 46bb559af1 Updated db_dumper.pl script print output formats [skip ci] 2016-08-27 01:41:09 -05:00
Akkadius 031a37baa1 Set eqemu_server.pl to check database manifest for only updates that are higher than the local database version - this will prevent false previous match conditions [skip ci] 2016-08-27 01:25:22 -05:00
Akkadius 62a4ce76b6 Merge branch 'master' of https://github.com/EQEmu/Server 2016-08-27 01:23:23 -05:00
Akkadius d85e6ae495 Set eqemu_server.pl to check database manifest for only updates that are higher than the local database version - this will prevent false previous match conditions [skip ci] 2016-08-27 01:23:03 -05:00
Akkadius 32c4c360bd Add IsHorse to default false in Mob constructor 2016-08-27 01:21:23 -05:00
Akkadius f2a075d432 Keep eqemu_server.pl from chown'ing the script to a pre-fixed user [skip ci] 2016-08-27 00:52:48 -05:00
Akkadius 2dee62c850 Refactor didn't save (oops) 2016-08-27 00:47:55 -05:00
Akkadius db380944ac Prevent horses (player mounts) from being depopped during a #repop 2016-08-27 00:46:45 -05:00
Kinglykrab 28c5b32624 Modified quantity in Merchant_Sell_Struct to be uint32 in accordance with Merchant_Purchase_Struct. This will allow you to buy stacks of items beyond 255. (Tested with a stack of 1,000 Arrows.) 2016-08-26 18:46:22 -04:00
Akkadius 6db350790e Merge branch 'master' of https://github.com/EQEmu/Server 2016-08-26 15:02:43 -05:00
Akkadius 3f8ff1373c Fix script call issue [skip ci] 2016-08-26 15:02:12 -05:00
Akkadius d6ee505c63 Merge pull request #548 from Natedog2012/master
Add TiltX and TiltY manipulation to objects (Perl)
2016-08-26 14:28:28 -05:00
Akkadius e84b2ba224 Merge pull request #546 from noudess/master
Mobs that path and then despawn do so whether zone idle or active
2016-08-26 14:26:50 -05:00
Natedog2012 4de9b2c53e Add TiltX and TiltY manipulation to objects (Perl)
Translate OP_GroundSpawn for Titanium

#perl plugin http://wiki.eqemulator.org/i?Module=Pastebin&Paste=u9IbA6Ql
2016-08-26 06:39:39 -07:00
Akkadius 385823461b Update eqemu_server.pl [skip ci] 2016-08-25 18:30:04 -05:00
Akkadius 85c28185a2 Update eqemu_server.pl - Add internet connection checks for people who are using EQEmu locally [skip ci] 2016-08-25 18:01:17 -05:00
Akkadius 25de25a777 Update eqemu_server.pl - Add internet connection checks for people using EQEmu locally [skip ci] 2016-08-25 18:00:13 -05:00
Akkadius 357a92dfee Update eqemu_server.pl [skip ci] 2016-08-25 16:46:34 -05:00
Akkadius 35c83db432 eqemu_server.pl - Run script after self upgrade regardless of OS [skip ci] 2016-08-25 16:43:35 -05:00
Akkadius f7cc1053f1 eqemu_server.pl - Update regardless of run condition [skip ci] 2016-08-25 16:39:35 -05:00
Akkadius d5864aea3e Few more adjustments [skip ci] 2016-08-25 16:36:48 -05:00
Akkadius 2b2d6e1ef5 Less fail [skip ci] 2016-08-25 16:33:50 -05:00
Akkadius f99523dc48 Migration to new EQEmu Server management script interface 2016-08-25 16:32:21 -05:00
Akkadius 69913c0897 Update eqemu_server.pl [skip ci] - More cleanup 2016-08-25 15:01:59 -05:00
Akkadius 75694e8797 Update eqemu_server.pl [skip ci] Testing self update 2016-08-25 13:00:57 -05:00
Akkadius 24856b6a2d Update eqemu_server.pl [skip ci] Testing self update 2016-08-25 12:56:30 -05:00
Akkadius a70291f20f Update eqemu_server.pl [skip ci] 2016-08-25 12:50:26 -05:00
Akkadius 6e1a5eac94 Update eqemu_server.pl [skip ci] 2016-08-25 12:17:24 -05:00
Akkadius 37b87e98f4 Update eqemu_server.pl [skip ci] 2016-08-25 01:18:03 -05:00
Michael Cook (mackal) 55d2e9b842 Only correct spell slots when we're sending to self
This will fix display issues with lots of buffs on NPCs
2016-08-24 23:15:31 -04:00
Akkadius 3afc5d0890 Update eqemu_server.pl [skip ci] 2016-08-24 21:03:23 -05:00
Akkadius f6b6fcc2c5 Update eqemu_server.pl 2016-08-24 20:38:56 -05:00
Paul Coene 5039aa07a5 updated changelog 2016-08-23 14:50:29 -04:00
Paul Coene 8048239a81 Merge remote-tracking branch 'upstream/master' 2016-08-23 13:55:52 -04:00
Paul Coene ecdc0f7096 Fixed so mobs that depop at end of pathgrid still path and depop
whiel zones are empty.  This makes these mobs no longer always appear
at start locations for the 1st person in a zone after long idle.
2016-08-23 13:54:51 -04:00
Akkadius 2c3107fbe9 Uploading initial eqemu_server.pl (was eqemu_update.pl) to start deprecrating of eqemu_update.pl and re-working of the structure of the script, more to come. 2016-08-22 16:07:44 -05:00
Michael Cook (mackal) c2b31bd6e2 Fix EVENT_ATTACK crash (thanks image)
Note: I guess we need to check if it's null in the actual quest too
2016-08-21 20:26:54 -04:00
Akkadius a8ba563632 Update eqemu_update.pl [skip ci] 2016-08-20 23:50:59 -05:00
Akkadius 4065df7930 Update eqemu_update.pl [skip ci]
Add option 21) Dump DB Player tables (Exports to backups\player_tables_export_(date).sql)
Player table list is referenced/maintained in utils/sql/character_table_list.txt
2016-08-20 23:49:51 -05:00
Akkadius 0b06044dce Update db_dumper [skip ci]
Fix issues with file name output when no compression is set
Add option to set backup_name="backup_name" to prefix backup outputs
2016-08-20 23:47:53 -05:00
Akkadius 93464e3963 Remove duplicate table [skip ci] 2016-08-20 23:32:01 -05:00
Akkadius 8dd18a43a0 Update db_dumper [skip ci] 2016-08-20 23:31:34 -05:00
Akkadius afe42ccdaf Update db_dumper.pl 2016-08-20 23:23:17 -05:00
Akkadius f5a7117bdf Add character_table_list.txt for database backup script reference 2016-08-20 23:13:16 -05:00
Michael Cook (mackal) 696c02c0f0 Move instrument mod outside of the EFFECT lop in SpellEffect 2016-08-20 14:30:54 -04:00
Akkadius 6daf207323 Quick test 2016-08-19 16:31:46 -05:00
Michael Cook (mackal) f67cd057f3 Fix issue with linked spell timers 2016-08-18 21:09:02 -04:00
Michael Cook (mackal) 0789d10d3e Add logging message for setting linked reuse 2016-08-18 20:51:58 -04:00
Akkadius a07149919d Pets now don't actually spawn until the player has fully entered the zone (Live-like) 2016-08-18 17:28:32 -05:00
Michael Cook (mackal) f9f3a8f3bd Expendable Arrows ignore EQ 2016-08-17 01:10:37 -04:00
Akkadius 1def512b4c One more test 2016-08-16 21:56:43 -05:00
Akkadius b85d5a6d98 Discord final test 2016-08-16 20:44:04 -05:00
Akkadius 94fabc87f0 Travis Discord test 2 2016-08-16 19:50:12 -05:00
Akkadius d3afde1aa1 Travis Discord test 2016-08-16 19:36:26 -05:00
Michael Cook (mackal) 5a0d2b527b Add a StopCasting function and make some use of it
Unsure if all of these cases should use interrupt or stop casting
2016-08-16 17:52:14 -04:00
Michael Cook (mackal) 3d64878e60 Skip OP_BeginCast for discs 2016-08-15 15:23:37 -04:00
Michael Cook (mackal) 26772b721c Fix overhaste stack check 2016-08-15 14:21:39 -04:00
Michael Cook (mackal) 3c95545ea3 Remove IsCasting check from Client::SendManaUpdatePacket 2016-08-15 01:23:47 -04:00
Michael Cook (mackal) ae5689ffb4 Clean up OP_ManaChange 2016-08-15 01:17:53 -04:00
Michael Cook (mackal) e894e96404 Implement Linked Spell Reuse Timers
They started linked spells at OoW launch (I think)

At least canni was linked then.

This is rather user unfriendly, but that's live like.
Ex. the spells aren't actually put on cool down so you can attempt to cast them
still but you will be interrupted.

Titanium is particularly unfriendly with large differences in reuse times
2016-08-14 23:32:27 -04:00
Akkadius ed5715ccd9 Merge pull request #540 from KinglyKrab/master
Added optional avoidance cap rules. Check changelog.txt.
2016-08-13 21:27:25 -05:00
Uleat 7f9af238f8 Fix for potential crash in ItemInst::GetTotalItemCount() 2016-08-13 19:51:12 -04:00
Michael Cook (mackal) fd1e425abc Fix potential crash in ucs/clientlist.cpp 2016-08-13 17:19:20 -04:00
Michael Cook (mackal) 35c1eccbe1 Fix potential crash in zone/worldserver.cpp 2016-08-13 17:15:57 -04:00
Michael Cook (mackal) 69f06f736c Fix potential crashes in zone/spells.cpp 2016-08-13 17:15:00 -04:00
Michael Cook (mackal) 48fb483de6 Fix typo 2016-08-13 17:05:48 -04:00
Michael Cook (mackal) 8ce2921e3d Fix potential crashes in Mob::SpellEffect 2016-08-13 16:45:32 -04:00
Michael Cook (mackal) f06a9b3dce use std::abs in Map::FindClosestZ 2016-08-13 15:58:02 -04:00
Michael Cook (mackal) 3efc925264 And another 2016-08-13 15:47:44 -04:00
Michael Cook (mackal) a8db4532d0 Fix potential crash in #iteminfo 2016-08-13 15:46:35 -04:00
Michael Cook (mackal) ab35f8b842 Fix memset in QuestReward 2016-08-13 15:39:08 -04:00
Michael Cook (mackal) ef3cf099b8 Fix potential crash in Sacrifice 2016-08-13 15:35:28 -04:00
Michael Cook (mackal) 00cfe2d25f Fix potential crashes in attack.cpp 2016-08-13 15:26:07 -04:00
Michael Cook (mackal) 7a4c9b36a8 Fix logic issue in SendAlternateAdvancementRank 2016-08-13 15:20:48 -04:00
Michael Cook (mackal) 488c4941d2 Fix potential crash 2016-08-13 15:19:10 -04:00
Michael Cook (mackal) 97dc0a84dd Fix logic paren issue 2016-08-13 15:14:31 -04:00
Michael Cook (mackal) f01c890966 Crash fix
The other thing needs to be looked at too, but I guess we never run
into an issue where this actually is a nullptr because bad things
would happen here ...
2016-08-13 15:09:43 -04:00
Kinglykrab 50de63117d Added optional avoidance cap rules. Check changelog.txt. 2016-08-13 07:19:58 -04:00
Michael Cook (mackal) 4e4d82857c Move OP_BeginCast above instant cast shortcut
For casted seplls, we should always see this. Mostly this shortcut breaks
spell awareness for NPC spells. (most of them are instant cast)
2016-08-12 22:07:03 -04:00
Michael Cook (mackal) 039e0fbb83 NPC innate procs overwrite TargetType to ST_Target 2016-08-12 21:53:14 -04:00
Michael Cook (mackal) e1a02455d8 Merge pull request #539 from clucksoft/crash_fix
Prevent crash in spell casting when group doesn't exist
2016-08-11 14:22:51 -04:00
Russell Kinasz c1c9ec2790 Prevent crash in spell casting when group doesn't exist 2016-08-11 11:04:03 -07:00
Michael Cook (mackal) e90e141a79 std::unordered_map::count is much slower than find 2016-08-10 23:51:06 -04:00
Michael Cook (mackal) 38d3f9b7c0 Client checks song flag first
This fixes bugs with buffs marked as disc and song (they go to the song window now)
Before the client got confused and gave up displaying them at all!
2016-08-10 13:16:32 -04:00
Michael Cook (mackal) 7d62b208ca Revert "Rate limit saving to at most once a second"
This reverts commit f26dce39c3.

No easy mode I guess
2016-08-09 21:30:10 -04:00
Michael Cook (mackal) 27f6826fd3 Add rule Spells:AllowItemTGB for custom servers 2016-08-08 20:21:38 -04:00
Michael Cook (mackal) 051f9ffab9 fix bard song mods on instant spells (nukes, procs) 2016-08-08 15:22:26 -04:00
Michael Cook (mackal) bdb083eac7 Previous disc buff check incorrectly excluded Savage Spirit AA line
This still doesn't fix Untamed Rage ... unsure on that one :(
2016-08-07 18:55:02 -04:00
Michael Cook (mackal) 4b93ef0a98 Fix SE_CastOnFadeEffect 2016-08-07 18:17:39 -04:00
Michael Cook (mackal) e86d11250b Actually remove expendable AAs from the DB 2016-08-07 14:32:30 -04:00
Michael Cook (mackal) e5746c3b2e Fix EVENT_LOOT broken by b43cfa126 2016-08-05 22:14:20 -04:00
Michael Cook (mackal) 6a7ea65dd0 Ask water map if we're in a zoneline to prevent false positives
I don't think this should open up any chance to exploit
Trying to use a ZL to go somewhere else is still detected etc

This should really cut down on false positives and we really can't
see real cheater from all the noise this creates
2016-08-05 01:07:12 -04:00
Michael Cook (mackal) 68df09a570 Implement PVP regions 2016-08-04 23:56:08 -04:00
Michael Cook (mackal) d53d569020 Port EQMacEmu's improved NPC stat scaling formula
Old formula can be used by setting NPC::NewLevelSacling to false
2016-08-04 22:12:33 -04:00
Michael Cook (mackal) 1d12f92934 Level 50+ NPCs will now respond to yells for help regardless of con color 2016-08-04 20:36:15 -04:00
Michael Cook (mackal) e89fa01d89 Port Aggro:UseLevelAggro from EQMacEmu
This will make level 18+ mobs braver
2016-08-04 20:33:29 -04:00
Uleat 4c49397ef6 Merge branch 'master' of https://github.com/EQEmu/Server 2016-08-04 16:12:58 -04:00
Michael Cook (mackal) 8dc8e53218 Added some more comments to PassCastRestrictions 2016-08-04 13:50:20 -04:00
Uleat d0fbbed20d Added a trap for Bot::GetNeedsCured() random crash (bot server admins: watch your logs!) 2016-08-04 07:09:34 -04:00
Michael Cook (mackal) 33407ee0da Forgot divination 2016-08-03 23:14:02 -04:00
Michael Cook (mackal) c81a5e0783 Limit casting skill ups to casting skills 2016-08-03 23:06:00 -04:00
Michael Cook (mackal) 66fec40169 Move Enrage check to after the immune ripo check 2016-08-03 22:38:33 -04:00
Michael Cook (mackal) 60f2d14caa Rework bash/kick stun based on client
This is what the client is doing. It doesn't reuse all the old rules, so those
can't be tweaked unless someone wants to add them back in
2016-08-03 17:37:09 -04:00
Michael Cook (mackal) 538d6a2a33 Hack to fix RNG Nature Veil line 2016-08-03 01:44:33 -04:00
Michael Cook (mackal) f26dce39c3 Rate limit saving to at most once a second
There are A LOT of unneeded saves ...

This will prevent a lot of excessive database hits at least
with very little room to exploit
2016-08-03 01:13:51 -04:00
Michael Cook (mackal) acb5bb3e3e If this flag is set, we JUST saved
Also saved due to an OP_Save very recently ...
2016-08-03 00:33:22 -04:00
Michael Cook (mackal) 16125c38af Lets not save here if we're zoning 2016-08-03 00:13:47 -04:00
Michael Cook (mackal) 69db67efe5 Remove extra save 2016-08-02 23:32:37 -04:00
Michael Cook (mackal) 37ecc69088 Update UF packet stuff to have 30 BUFF_COUNT 2016-08-02 21:10:32 -04:00
Michael Cook (mackal) d68a3b191e Give pets 30 buff because that's what they got 2016-08-02 21:08:05 -04:00
Michael Cook (mackal) 64cf613189 Update GetCurrentBuffSlots() for TSS free slots
The client also checks if you have any bonus from spells and items
so why not check that as well
2016-08-02 19:00:33 -04:00
Uleat f3da7773d3 Merge branch 'master' of https://github.com/EQEmu/Server 2016-08-02 17:49:17 -04:00
Uleat 7c9bd80c1e Changed SendZoneSpawnsBulk to a more like-like behavior 2016-08-02 17:49:08 -04:00
Michael Cook (mackal) 2bae779a9b NPCs don't have separate buff windows 2016-08-02 16:48:58 -04:00
Michael Cook (mackal) e862994716 RoF/RoF2 spell gem refresh in PP
This fixes issues with long recast spells
2016-07-31 18:09:04 -04:00
Michael Cook (mackal) f612f8be42 Fix typo 2016-07-31 17:35:33 -04:00
Michael Cook (mackal) ef2c17748e Implement extra spell gems!
New limits:
    Tit: 9
    SoF: 9
    SoD: 10
    UF: 12
    RoF: 12
    RoF2: 12

The SoF client doesn't actually support 10 like SoF should
RoF/RoF2 actually have 4 extra broken spell gems in the UI. They don't work and
will likely crash your client

Quest stuff assumes you are passing in valid slots.
(note the old default of 10 should be 22)

There are still somethings to do like clean up the memmed spells if one switches
to an older client that doesn't support as many as their previous client.
2016-07-31 17:16:23 -04:00
Michael Cook (mackal) 4c4b0aba0c Switch trading to call CommonBreakInvisible() 2016-07-30 12:51:17 -04:00
Uleat 4decdb3e4d Added zone map mmf discovery message 2016-07-29 21:58:42 -04:00
Uleat 6b3078d0f7 Fix for 64-bit Zone MMF compiles 2016-07-29 18:26:23 -04:00
Michael Cook (mackal) 3a4b341ad6 Allow quest controlled TS to have no returns 2016-07-29 15:29:28 -04:00
Michael Cook (mackal) 2a2ce6da5d Fix item clicks being TGBable 2016-07-29 15:14:26 -04:00
Michael Cook (mackal) 239c478f31 Add some comments to target types [skip ci] 2016-07-29 02:55:43 -04:00
Michael Cook (mackal) f6c62af82e Update comment [skip ci] 2016-07-29 02:26:26 -04:00
Uleat 84db0ec2c5 Zone MMF Implementation (for map files) 2016-07-28 22:50:06 -04:00
Michael Cook (mackal) 345f3d6301 Fix Tit OP_Buff decode 2016-07-27 19:58:24 -04:00
Michael Cook (mackal) de5170c5cb Fix mana burn 2016-07-26 17:10:06 -04:00
Michael Cook (mackal) 7674b3a077 Fix some same spell stacking issues 2016-07-26 16:25:19 -04:00
Michael Cook (mackal) 11e017ccb9 Fix bard mod in PP for UF 2016-07-25 16:37:27 -04:00
Michael Cook (mackal) bda4fcfb26 Fix up SpellBuff struct
Please report any bugs you find. There shouldn't be unless I messed up the struct
for a client I didn't throughly test for
2016-07-25 16:22:48 -04:00
Michael Cook (mackal) a7fd9312d0 Fix syntax error 2016-07-24 22:58:48 -04:00
Michael Cook (mackal) 3963897fe4 There is a different rez spell depending on race 2016-07-24 22:53:57 -04:00
Michael Cook (mackal) f42b0351fd Improve list of skipped effects in stacking code
This is the list according to the client (RoF2)

Please report any stacking anomalies
2016-07-24 22:24:53 -04:00
Uleat 37cb9f00f6 Removed another unneeded slash 2016-07-24 18:01:14 -04:00
Michael Cook (mackal) 343b781e74 Implement cast_not_standing and fix Cazic Touch
No idea why this spell field does this, but that's what the client
is doing with it ...
2016-07-23 18:40:17 -04:00
Michael Cook (mackal) f428a8a56a Add a CastWhileInvis check and fix some issues 2016-07-23 18:07:56 -04:00
Michael Cook (mackal) cd9a7f1d5d Cap tic diff to 0 for duration based calcs
This will match Splurt with the double 191
2016-07-23 17:52:30 -04:00
Michael Cook (mackal) 83548ee405 Fix buff tics
This will not fade buffs at 6s :P
2016-07-23 17:41:16 -04:00
Michael Cook (mackal) 5f588934a9 Make decaying spell bonuses not depend on CaclBonuses being called some other way
This just sets a flag that will tell us we need to recalc bonuses every tick

Before these kind of depended on it being caused some other way
2016-07-23 13:55:36 -04:00
Michael Cook (mackal) 1f5dcb6965 Make SE_SpellResistReduction not complain 2016-07-21 20:27:08 -04:00
Michael Cook (mackal) 5f111f159b Update comment [skip ci] 2016-07-21 14:05:29 -04:00
Michael Cook (mackal) 527ee56fb2 Fix Distance Mod scaling
The client clamps the distance between the min/max
2016-07-20 17:49:33 -04:00
Michael Cook (mackal) 8396f19e85 Add buff level restrictions for pets 2016-07-20 16:27:22 -04:00
Akkadius aadc4b5e6b Update eqemu_update.pl 2016-07-20 14:15:00 -05:00
Michael Cook (mackal) ccb5427b45 Make VS debug mode happy
This actually hurts microbenchmarking

I couldn't get the ModelEntry::polys vector to play nice with benchmarking
so it will just be using push_back so I don't have write a new ctor
(writing a new ctor and using emplace_back vs push_back were equal)
2016-07-18 21:57:25 -04:00
Michael Cook (mackal) 8983f3c5dc Merge pull request #537 from noudess/master
Fix for BuffDurationPacket on movement speed buffs.
2016-07-18 16:05:28 -04:00
Paul Coene 9349d5d473 Another fix for when BuffDurationPacket breaks client effects on spells.
In this case run speed spells like SoW.
2016-07-18 15:30:55 -04:00
JJ ae6ceddab7 Merge pull request #536 from noudess/master
Fix Voice Graft to work only when targetting pet.
2016-07-18 14:54:43 -04:00
Paul Coene 84c90715be Reverse checks for voice graft to short curcuit when no pet. 2016-07-18 14:37:21 -04:00
Michael Cook (mackal) aeff31ba7a Fix error with /setstartcity 2016-07-18 13:57:14 -04:00
Michael Cook (mackal) f431e820ef Optimize Map::LoadV2 a bit
Microbenchmarking showed ~33% increase in loading moors
Real world testing showed ~48%
2016-07-17 23:35:18 -04:00
Michael Cook (mackal) c41521c310 Fix saving binds on charcreate 2016-07-17 22:50:00 -04:00
Akkadius f437232db1 Overhauled worldserver logging
- Now displays account logins
 - Zoning from character select
 - Zoning from zone to zone
 - When any other server process connects to world
 - Adjust some zone bootup messages etc.

Adjusted logging code bits all over and refactored variables for readability etc.
2016-07-17 20:45:58 -05:00
Akkadius 3ed43d50f2 Resolving glitchy/choppy mob pathing issues 2016-07-17 19:07:48 -05:00
Michael Cook (mackal) 7cd613e5f2 Comment spell struct with official names for each field 2016-07-17 02:13:13 -04:00
Michael Cook (mackal) 921136c987 Exclude in other Perma Illusion spot 2016-07-16 19:40:20 -04:00
Michael Cook (mackal) d4df2e7351 Exclude Minor Illusion and Illusion: Tree from perma 2016-07-16 19:33:36 -04:00
Michael Cook (mackal) 9cf553232d Tweak spell dot stacking exempt based on client 2016-07-16 18:18:41 -04:00
Uleat 6cb2fdd737 Changed constructor call for stringstream in ClientTaskState::EnableTask/DisableTask (write position issues) 2016-07-15 19:32:46 -04:00
Michael Cook (mackal) bbf4d19de3 Revert "Changed tuple use to struct in maps.cpp (LoadV2) (should help in client drops where slow zone boot-ups are a factor)"
This reverts commit 02cedce54e.

This is breaks moors!
2016-07-15 15:20:36 -04:00
Uleat 02cedce54e Changed tuple use to struct in maps.cpp (LoadV2) (should help in client drops where slow zone boot-ups are a factor) 2016-07-14 13:22:36 -04:00
Uleat 871fcd1fc8 Fix for quest enabletask/disabletask api queries 2016-07-14 12:47:55 -04:00
Uleat 7457d832f8 Changed query in BotDatabase::LoadGroupedBotsByGroupID() to use standard table query over view use (should help in cases where players time-out when zoning) 2016-07-12 20:22:14 -04:00
Michael Cook (mackal) a9ff407657 Optimize Mapp:RotateVertex()
This function can get rather expensive and waste a surprisingly
large amount of time. Using moors as a test zone simply switching
from the C math API cos/sin to std::cos/std::sin seemed to help

11.11% Map::RotateVertex(glm::tvec3<float, (glm::precision)0>&, float, float, float)
4.16% Map::RotateVertex(glm::tvec3<float, (glm::precision)0>&, float, float, float)
2016-07-10 23:18:26 -04:00
Paul Coene 1ba7f0cd65 Fix so you can still speak to NPCS (patch to last patch for voice graft) 2016-07-09 16:35:57 -04:00
Paul Coene 56fcabc119 Fix Voice Graft to allow you to speak by targetting yourself. 2016-07-09 15:40:19 -04:00
Uleat 402353affa Important fix for mob pathing (see changelog.txt) 2016-07-09 03:10:54 -04:00
Uleat bc196f2e50 Changed world server zone boot-up failure message to 'General' level to facilitate world-initiated zone boot-up issues 2016-07-08 16:19:14 -04:00
Uleat 148eaf7048 Merge branch 'master' of https://github.com/EQEmu/Server 2016-07-08 15:33:42 -04:00
Uleat b44da7c13a Fix for command #traindisc not saving disciplines when not used on self 2016-07-08 15:33:36 -04:00
Michael Cook (mackal) 4b57f69cba Fix illusions on zone 2016-07-07 16:17:13 -04:00
Uleat 542d454fe0 Added rule 'NPC:UseClassAsLastName' to second spawn packet handler 2016-07-05 15:20:46 -04:00
Uleat 3d61df253d Added rule 'NPC:UseClassAsLastName' to allow certain npcs' class names to be hidden 2016-07-03 19:44:45 -04:00
Akkadius dcd276a5ce Merge pull request #534 from fzzzt/master
Add FreeBSD as a peer with Linux in eqemu_update.pl OS detection
2016-07-03 15:56:11 -05:00
Josh Endries bacaf6453e Add FreeBSD as a peer with Linux in eqemu_update.pl OS detection 2016-07-03 15:13:34 -04:00
Michael Cook (mackal) 860ee81a38 Break invis for AA casts 2016-06-30 21:59:50 -04:00
Michael Cook (mackal) bcec9501b7 Fix issue with invis not dropping for new item clicks
Clients using OP_ItemVerifyRequest couldn't break the invis
themselves, so we gotta for them
2016-06-30 21:49:20 -04:00
Michael Cook (mackal) 37b46d1289 Make more usage of CancelSneakHide 2016-06-30 21:49:00 -04:00
Michael Cook (mackal) 54de212214 Implement OP_CancelSneakHide
Didn't test every client, but they should all work
2016-06-30 17:50:31 -04:00
Michael Cook (mackal) a64343689c Refactor loot response a bit
Invis is dropped after ALL error checking now
Identified all the response types
2016-06-30 14:00:18 -04:00
Michael Cook (mackal) 3e0af2928b Remove duped code from CommonBreakInvisibleFromCombat 2016-06-30 01:30:51 -04:00
Uleat a5d79b25db Grr... 2016-06-28 16:56:42 -04:00
Uleat cb8843926c Merge branch 'master' of https://github.com/EQEmu/Server
# Conflicts:
#	changelog.txt
2016-06-28 16:20:17 -04:00
Michael Cook (mackal) 59ec184208 Merge pull request #533 from noudess/master
Res effects now block certain buffs like on live.  Blocked spells generate message like on live.
2016-06-28 13:34:39 -04:00
Paul Coene 9a010a90a9 Added Client:UseLiveBlockedMessage rule 2016-06-28 08:27:31 -04:00
Uleat 3d6fe8acba Fix for bot inventory save failure involving items with unlimited charges 2016-06-28 07:58:38 -04:00
Paul Coene 02ec76d2aa Res effects now block certain buffs like on live.
Blocked spells generate message as on live.
2016-06-27 11:14:33 -04:00
Natedog2012 8615df0a03 Bot names skip player name filter to allow for longer bot names.
RoF/RoF2/UF item packets allow for 1000 stack items again.. not capped at 254
2016-06-25 18:05:44 -07:00
Uleat 951f3239f1 Added rule Bots:AllowCamelCaseNames 2016-06-23 22:25:57 -04:00
Akkadius fe630bf7ca Adjust default lootdrop max level 2016-06-20 14:27:01 -05:00
Akkadius 1a2537f5d8 Adjust default lootdrop max level 2016-06-20 14:25:05 -05:00
Natedog2012 7b04b9ef4a Fix for #bot command crashing the zone when sent with no text following "#bot" 2016-06-18 23:37:17 -07:00
Michael Cook (mackal) 30b516e7bd Merge pull request #530 from EQEmu/luarocks
Add luarocks support
2016-06-17 21:09:40 -04:00
Akkadius c72749790d Update eqemu_update.pl 2016-06-16 13:14:27 -05:00
Akkadius 05780a9316 Update eqemu_update.pl 2016-06-16 02:17:11 -05:00
Akkadius 3889da7301 Update eqemu_update.pl [skip ci] 2016-06-15 02:02:32 -05:00
Michael Cook (mackal) 57ebfd2675 Merge pull request #532 from noudess/master
Changed personal faction earned min/max values to -2000/2000.
2016-06-13 14:30:39 -04:00
Paul Coene b10187f9de Changed personal faction earned min/max values to -2000/2000. 2016-06-13 14:04:23 -04:00
Michael Cook (mackal) af99db7287 Merge pull request #531 from noudess/master
Fix for detrimental/beneficial spell overwrite and/or block.
2016-06-13 13:27:41 -04:00
Paul Coene 306ecf003a Spells like listless power and dread touch should be taking down/blocking
spells like augmentation and strenthen respectively.  The stacking code
was being bypassed when a beneficial spell and a detrimental spell for the
same effect were being compared.

With this code removed, the spells are compared and the stonger of the two
spells wins and replaces or blocks the other.

Without this change, for example, dread touch takes down strengthen on the
client, but the server still things strength is up, causing a mismatch.

With this change, client/server match.
2016-06-13 09:06:44 -04:00
Michael Cook (mackal) 2b2ebc75b0 Add luarocks support
This allows one to use the lua_modules folder as their luarocks tree
ex (from the server folder with lua_modules using default location)

luarocks --tree=lua_modules install luasql-mysql MYSQL_INCDIR=/usr/include

This will install the luasql mysql module so you can now do queries from lua
2016-06-11 15:59:46 -04:00
Michael Cook (mackal) 83bb10b32b Add support for sub folder style lua modules
Ex. lua_modules/?/init.lua will work (which some lua modules do use)
2016-06-11 13:23:52 -04:00
Drajor d9bdcf2aec Merge pull request #529 from EQEmu/currency
Currency
2016-06-11 21:04:38 +10:00
Drajor 3e25a3df5c Implemented RoF2 encoder for OP_CrystalCountUpdate (0x467f) 2016-06-11 20:24:36 +10:00
Drajor 73e91be281 Fixed vulnerability in handling of OP_CrystalCreate 2016-06-11 19:53:19 +10:00
Michael Cook (mackal) 471d7ec42d Merge pull request #528 from EQEmu/altcurr
Fixes #527
2016-06-10 23:31:43 -04:00
Drajor 1b6974ade3 Alternate currency sell price now matches RoF2 client calculation 2016-06-11 13:29:56 +10:00
Drajor c1a6a23e06 Fixes #527 2016-06-11 12:48:16 +10:00
Uleat 9ec299247c Reworked EQEmuDictionary to use class LookupEntry 2016-06-06 21:59:42 -04:00
Uleat 79549ba330 Merge branch 'master' of https://github.com/EQEmu/Server 2016-06-04 20:05:04 -04:00
JJ 4b15121f70 No need to have extra slash anymore due to b997a040d7 2016-06-04 19:53:22 -04:00
Uleat c29219f214 Split InventoryVersion::Pet into discrete sub-types 2016-06-04 07:04:31 -04:00
KimLS 51d8f00418 Add appveyor badge to readme (wip but still). 2016-06-02 20:12:41 -07:00
Uleat e843f66135 Cosmetic fix to match existing naming conventions 2016-06-02 20:19:40 -04:00
Uleat 542dc16752 Fix for bandolier 2H-weapon exploit 2016-06-02 20:07:25 -04:00
Uleat 62888170b0 Better the second time around... 2016-06-02 07:14:54 -04:00
Uleat ca0b26f89f Implementation clean-up 2016-06-01 09:34:16 -04:00
Uleat cd8cd90a38 Implemented EQEmu::TextureProfile 2016-06-01 08:54:26 -04:00
Uleat ae3c98c692 Implemented EQEmu::TintProfile 2016-06-01 04:58:52 -04:00
Uleat 767dfaef70 Another penguin bite... 2016-05-31 22:28:31 -04:00
Uleat c07fe35908 Fix for gcc failure 2016-05-31 22:17:58 -04:00
Uleat ea8f81feec Converted enumeration MaterialSlots to EQEmu::textures::TextureSlot 2016-05-31 22:07:02 -04:00
Uleat a38417bf54 More eq_dictionary work - added invtype persistence checks 2016-05-31 19:12:54 -04:00
Uleat 0f54984966 Missed a few out of my working stash... 2016-05-31 01:52:51 -04:00
Uleat 6c1af93f58 Another lightsource/saylink/skills pass 2016-05-30 08:39:49 -04:00
Uleat 16895910e4 Another eq_dictionary pass 2016-05-30 06:52:25 -04:00
Uleat b155a603aa Added multi-type EQEmu::ValueWithin function 2016-05-30 03:32:01 -04:00
Uleat ecc9e41ab2 Fix for server crash related to deleting a bot with a spawned pet 2016-05-30 03:03:55 -04:00
Uleat 2a74d04635 Added offline client inventory version definitions and convertors 2016-05-29 20:30:03 -04:00
Uleat a089820464 Merged client_version and inventory_version into emu_versions files 2016-05-28 04:44:14 -04:00
Uleat 579efe83af Renamed EQEmu::Item_Struct to EQEmu::ItemBase to coincide with new inventory naming conventions (re-run shared_memory.exe) 2016-05-27 22:22:19 -04:00
Uleat a37a811014 Imported memory_buffer files from inv2 branch 2016-05-27 20:39:11 -04:00
Uleat 0ecc702612 ItemPacketType updates 2016-05-27 03:38:13 -04:00
Uleat a144ecd21b ItemPacketType note update 2016-05-26 17:23:57 -04:00
Uleat 772fa200ac Update to client limits 2016-05-26 05:27:21 -04:00
929 changed files with 212083 additions and 7007 deletions
+16 -5
View File
@@ -30,6 +30,7 @@
#EQEMU_BUILD_LUA
#EQEMU_SANITIZE_LUA_LIBS
#EQEMU_BUILD_CLIENT_FILES
#EQEMU_USE_MAP_MMFS
#EQEMU_MAP_DIR
#We set a fairly new version (as of 2013) because I found finding perl was a bit... buggy on older ones
@@ -275,6 +276,11 @@ IF(EQEMU_BUILD_LUA)
ADD_DEFINITIONS(-DLUA_EQEMU)
ENDIF(EQEMU_BUILD_LUA)
OPTION(EQEMU_USE_MAP_MMFS "Create and use Zone Map MMF files." OFF)
IF(EQEMU_USE_MAP_MMFS)
ADD_DEFINITIONS(-DUSE_MAP_MMFS)
ENDIF(EQEMU_USE_MAP_MMFS)
SET(EQEMU_MAP_DIR "./Maps" CACHE STRING "The dir that maps, water maps, and paths are located in.")
ADD_DEFINITIONS(-DEQDEBUG=${EQEMU_DEBUG_LEVEL})
@@ -317,7 +323,8 @@ 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}")
INCLUDE_DIRECTORIES(SYSTEM "${CMAKE_CURRENT_SOURCE_DIR}/libs/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)
@@ -325,14 +332,18 @@ 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}")
INCLUDE_DIRECTORIES(SYSTEM "${MySQL_INCLUDE_DIR}")
INCLUDE_DIRECTORIES(SYSTEM "${CMAKE_CURRENT_SOURCE_DIR}/common/glm")
INCLUDE_DIRECTORIES(SYSTEM "${CMAKE_CURRENT_SOURCE_DIR}/libs/cereal")
INCLUDE_DIRECTORIES(SYSTEM "${CMAKE_CURRENT_SOURCE_DIR}/libs/libuv/include" )
INCLUDE_DIRECTORIES(SYSTEM "${CMAKE_CURRENT_SOURCE_DIR}/libs/libuv/src")
INCLUDE_DIRECTORIES(SYSTEM "${CMAKE_CURRENT_SOURCE_DIR}/libs/format")
IF(EQEMU_BUILD_SERVER OR EQEMU_BUILD_LOGIN OR EQEMU_BUILD_TESTS)
ADD_SUBDIRECTORY(common)
ADD_SUBDIRECTORY(libs)
ENDIF(EQEMU_BUILD_SERVER OR EQEMU_BUILD_LOGIN OR EQEMU_BUILD_TESTS)
IF(EQEMU_BUILD_SERVER)
ADD_SUBDIRECTORY(shared_memory)
+39 -33
View File
@@ -1,53 +1,59 @@
EQEmu
===
# EQEmulator Core Server
|Travis CI (Linux)|Appveyor (Windows) |
|:---:|:---:|
|[![Linux CI](https://travis-ci.org/EQEmu/Server.svg?branch=master)](https://travis-ci.org/EQEmu/Server) |[![Windows CI](https://ci.appveyor.com/api/projects/status/d0cvokm7u732v8vl/branch/master?svg=true)](https://ci.appveyor.com/project/KimLS/server/branch/master) |
[![Build Status](https://travis-ci.org/EQEmu/Server.svg?branch=master)](https://travis-ci.org/EQEmu/Server)
***
Overview
---
**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
EQEmu is a custom server implementation for EverQuest
## Server Installs
||Windows|Linux|
|:---:|:---:|:---:|
|**Install Count**|![Windows Install Count](http://analytics.akkadius.com/?install_count&windows_count)|![Linux Install Count](http://analytics.akkadius.com/?install_count&linux_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)
Dependencies
---
### > Debian/Ubuntu
For Windows: http://eqemu.github.io
> 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
Login Server dependencies for Windows/Linux/OSX: http://eqemu.github.io
### > CentOS/Fedora
For Debian based distros (adjust to your local flavor):
> curl -O https://raw.githubusercontent.com/EQEmu/Server/master/utils/scripts/linux_installer/install.sh install.sh && chmod 755 install.sh && ./install.sh
- libmysqlclient-dev
- libperl-dev
- liblua5.1-0-dev (5.2 should work as well)
- libboost-dev
## Supported Clients
Further instructions on building the source can be found on the
[wiki](http://wiki.eqemulator.org/i?M=Wiki).
|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">|
Bug reports
---
Please use the [issue tracker](https://github.com/EQEmu/Server/issues) provided by GitHub to send us bug
## 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
reports or feature requests.
* The [EQEmu Forums](http://www.eqemulator.org/forums/) are also a place to submit and get help with bugs.
The [EQEmu Forums](http://www.eqemulator.org/forums/) also have forums to submit
bugs/get help with bugs.
## Contributions <img src="http://image.flaticon.com/icons/png/512/25/25231.png" width="20">
Contributions
---
The preferred way to contribute is to fork the repo and submit a pull request on
* 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 IRC. You can also post unified diffs (`git diff` should do the trick) on the
try Discord. 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
---
- **User IRC Channel**: `#eqemu` on `irc.eqemulator.net`
- **Developer IRC Channel**: `#eqemucoders` on `irc.eqemulator.net`
## 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
---
- [EQEmulator Forums](http://www.eqemulator.org/forums)
- [EQEmulator Wiki](http://wiki.eqemulator.org/i?M=Wiki)
+94
View File
@@ -1,5 +1,99 @@
EQEMu Changelog (Started on Sept 24, 2003 15:50)
-------------------------------------------------------
== 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.
- Titanium is especially unfriendly with large differences in reuse times (ex higher canni and the first 4)
- Unsure when this went live for spells, but canni was at least linked at OoW launch
== 08/13/2016 ==
Kinglykrab: Implemented optional avoidance cap rules.
- Serves to eliminate God-like characters on custom servers with high item stats
- Rule Names:
- Character:EnableAvoidanceCap (default is false)
- Character:AvoidanceCap (default is 750, beyond 1,000 seems to make characters dodge all attacks)
== 08/02/2016 ==
Uleat: Changed 'SendZoneSpawnsBulk' behavior to use near/far criteria (live-like) when sending packets.
- Zone-to-Zone client loading will see a small decrease in time (less than 10~15%)
- World-to-Zone client loading appears to greatly benefit from this (tested 'devastation' - pre-change: ~22 seconds, post-change: 12~15 seconds)
- This change does not affect the final spawning of mobs in the client
== 07/31/2016 ==
mackal: Implement more spell gems!
- There are a few things still left to due like make dealing with losing gems nice (reset AAs, going to an older client etc)
- Sadly SoF disc release doesn't support gem 10 like one might expect :(
- So changed clients:
- SoD = 10
- UF = 12
- RoF/RoF2 = 12. I know the UI supports 16, but the client does not and can cause client crashes
- The quest APIs assume you pass a valid spell gem ...
== 07/28/2016 ==
Uleat: Implemented zone memory-mapped file usage
- Zone map files are converted to pre-loaded binary files, bypassing the (sometimes) time-consuming raw data transform process
- There are three ways to convert files:
-- Do nothing! The zone bootup process will check for a mmf file and load it, if found, or create it after the 'normal' transform process is complete
-- Use the command line option: zone convert_map <zone_name>.map (for singular conversions)
-- Drop the 'convert_maps_to_mmfs.pl' into your server directory and execute it for a batch conversion
-- Note: Any zone maps not pre-converted will be processed once a zone is booted up that does not have one
- To enable this feature, you must have the 'USE_MAP_MMFS' option checked in cmake and have built binaries on that
- To disable this feature, or if you encouter problems, disable the 'USE_MAP_MMFS' option and rebuild your binaries
- This feature will test the validity of your zlib library. If you get errors/crashes upon conversion, then your zlib1.dll is most likely suspect (check our forum for solutions)
== 07/25/2016 ==
mackal: Fix up the SpellBuff struct
- THERE MAYBE BUGS
- there shouldn't though, most of the hackery was from badly named fields causing confusion
== 07/09/2016 ==
Uleat: Important fix for mob pathing
- This should fix failed pathing issues (and high cpu usage for zone.exe) for mobs in affect zones
- Changed variable 'gridno' type from int16 to int32 to reflect actual return value of fetch (values do exceed 32767 aka int16.max)
- Precision loss from int32 to int16 conversion was causing grid id to be changed to quest controlled movement in cases where (gridno & 0x8000 == true)
== 06/28/2016 ==
Noudess: Resurrection effects now block certain buffs like on live.
Noudess: Added message about why spells are blocked (rule based)
Noudess: Added new rule: Client:UseLiveBlockedMessage
Uleat: Fix for bot inventory save failure involving items with unlimited charges
== 06/13/2016 ==
Noudess: Changes personal faction earned min/max to -2000/2000 from -3000/1200
== 06/06/2016 ==
Uleat: Reworked EQEmuDictionary to use class LookupEntry
== 06/01/2016 ==
Uleat: Implemented EQEmu::TintProfile
Uleat: Implemented EQEmu::TextureProfile
== 05/31/2016 ==
Uleat: Converted enumeration MaterialSlots to EQEmu::textures::TextureSlot
== 05/28/2016 ==
Uleat: Merged client_version and inventory_version into emu_versions files
== 05/27/2016 ==
Uleat: Renamed EQEmu::Item_Struct to EQEmu::ItemBase (and appropriate files) to coincide with new inventory naming conventions
== 05/25/2016 ==
Uleat: Renamed and moved enumeration SkillUseTypes to EQEmu::skill::SkillType - added class EQEmu::SkillProfile, though not implemented at this time
Uleat: Some more work on eq_dictionary
+1 -2
View File
@@ -9,7 +9,7 @@ SET(export_headers
ADD_EXECUTABLE(export_client_files ${export_sources} ${export_headers})
INSTALL(TARGETS export_client_files RUNTIME DESTINATION ${CMAKE_INSTALL_PREFIX})
INSTALL(TARGETS export_client_files RUNTIME DESTINATION ${CMAKE_INSTALL_PREFIX}/bin)
TARGET_LINK_LIBRARIES(export_client_files common debug ${MySQL_LIBRARY_DEBUG} optimized ${MySQL_LIBRARY_RELEASE} ${ZLIB_LIBRARY})
@@ -30,7 +30,6 @@ IF(UNIX)
TARGET_LINK_LIBRARIES(export_client_files "rt")
ENDIF(NOT DARWIN)
TARGET_LINK_LIBRARIES(export_client_files "pthread")
ADD_DEFINITIONS(-fPIC)
ENDIF(UNIX)
SET(EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR}/bin)
+1 -2
View File
@@ -9,7 +9,7 @@ SET(import_headers
ADD_EXECUTABLE(import_client_files ${import_sources} ${import_headers})
INSTALL(TARGETS import_client_files RUNTIME DESTINATION ${CMAKE_INSTALL_PREFIX})
INSTALL(TARGETS import_client_files RUNTIME DESTINATION ${CMAKE_INSTALL_PREFIX}/bin)
TARGET_LINK_LIBRARIES(import_client_files common debug ${MySQL_LIBRARY_DEBUG} optimized ${MySQL_LIBRARY_RELEASE} ${ZLIB_LIBRARY})
@@ -30,7 +30,6 @@ IF(UNIX)
TARGET_LINK_LIBRARIES(import_client_files "rt")
ENDIF(NOT DARWIN)
TARGET_LINK_LIBRARIES(import_client_files "pthread")
ADD_DEFINITIONS(-fPIC)
ENDIF(UNIX)
SET(EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR}/bin)
+64 -7
View File
@@ -3,7 +3,6 @@ CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
SET(common_sources
base_packet.cpp
classes.cpp
client_version.cpp
condition.cpp
crash.cpp
crc16.cpp
@@ -19,6 +18,7 @@ SET(common_sources
emu_opcodes.cpp
emu_tcp_connection.cpp
emu_tcp_server.cpp
emu_versions.cpp
eqdb.cpp
eqdb_res.cpp
eqemu_exception.cpp
@@ -35,12 +35,12 @@ SET(common_sources
faction.cpp
guild_base.cpp
guilds.cpp
inventory_version.cpp
ipc_mutex.cpp
item.cpp
item_struct.cpp
item_base.cpp
light_source.cpp
md5.cpp
memory_buffer.cpp
memory_mapped_file.cpp
misc.cpp
misc_functions.cpp
@@ -68,12 +68,21 @@ SET(common_sources
struct_strategy.cpp
tcp_connection.cpp
tcp_server.cpp
textures.cpp
timeoutmgr.cpp
timer.cpp
unix.cpp
worldconn.cpp
xml_parser.cpp
platform.cpp
net/crc32.cpp
net/daybreak_connection.cpp
net/eqstream.cpp
net/packet.cpp
patch/chat.cpp
patch/login_sod.cpp
patch/login_titanium.cpp
patch/patch.cpp
patches/patches.cpp
patches/sod.cpp
patches/sod_limits.cpp
@@ -111,7 +120,6 @@ SET(common_headers
base_data.h
bodytypes.h
classes.h
client_version.h
condition.h
crash.h
crc16.h
@@ -127,6 +135,7 @@ SET(common_headers
emu_oplist.h
emu_tcp_connection.h
emu_tcp_server.h
emu_versions.h
eq_constants.h
eq_packet_structs.h
eqdb.h
@@ -154,17 +163,17 @@ SET(common_headers
global_define.h
guild_base.h
guilds.h
inventory_version.h
ipc_mutex.h
item.h
item_base.h
item_fieldlist.h
item_struct.h
languages.h
light_source.h
linked_list.h
loottable.h
mail_oplist.h
md5.h
memory_buffer.h
memory_mapped_file.h
misc.h
misc_functions.h
@@ -199,6 +208,7 @@ SET(common_headers
tcp_basic_server.h
tcp_connection.h
tcp_server.h
textures.h
timeoutmgr.h
timer.h
types.h
@@ -208,6 +218,19 @@ SET(common_headers
worldconn.h
xml_parser.h
zone_numbers.h
event/background_task.h
event/event_loop.h
event/timer.h
net/crc32.h
net/daybreak_connection.h
net/daybreak_structs.h
net/endian.h
net/eqstream.h
net/packet.h
patch/chat.h
patch/login_sod.h
patch/login_titanium.h
patch/patch.h
patches/patches.h
patches/sod.h
# patches/sod_itemfields.h
@@ -259,6 +282,37 @@ SET(common_headers
StackWalker/StackWalker.h
tinyxml/tinystr.h
tinyxml/tinyxml.h
util/memory_stream.h
)
SOURCE_GROUP(Event FILES
event/background_task.h
event/event_loop.h
event/timer.h
)
SOURCE_GROUP(Net FILES
net/crc32.cpp
net/crc32.h
net/daybreak_connection.cpp
net/daybreak_connection.h
net/daybreak_structs.h
net/endian.h
net/eqstream.h
net/eqstream.cpp
net/packet.cpp
net/packet.h
)
SOURCE_GROUP(Patch FILES
patch/chat.cpp
patch/chat.h
patch/login_sod.cpp
patch/login_sod.h
patch/login_titanium.cpp
patch/login_titanium.h
patch/patch.cpp
patch/patch.h
)
SOURCE_GROUP(Patches FILES
@@ -353,12 +407,15 @@ SOURCE_GROUP(TinyXML FILES
tinyxml/tinyxmlparser.cpp
)
SOURCE_GROUP(Util FILES
util/memory_stream.h
)
INCLUDE_DIRECTORIES(Patches SocketLib StackWalker TinyXML)
ADD_LIBRARY(common ${common_sources} ${common_headers})
IF(UNIX)
ADD_DEFINITIONS(-fPIC)
SET_SOURCE_FILES_PROPERTIES("SocketLib/Mime.cpp" PROPERTY COMPILE_FLAGS -Wno-unused-result)
SET_SOURCE_FILES_PROPERTIES("patches/sod.cpp" "patches/sof.cpp" "patches/rof.cpp" "patches/rof2.cpp" "patches/uf.cpp" PROPERTIES COMPILE_FLAGS -O0)
ENDIF(UNIX)
-128
View File
@@ -1,128 +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 "client_version.h"
bool EQEmu::versions::IsValidClientVersion(ClientVersion client_version)
{
if (client_version <= ClientVersion::Unknown || client_version > LastClientVersion)
return false;
return true;
}
EQEmu::versions::ClientVersion EQEmu::versions::ValidateClientVersion(ClientVersion client_version)
{
if (client_version <= ClientVersion::Unknown || client_version > LastClientVersion)
return ClientVersion::Unknown;
return client_version;
}
const char* EQEmu::versions::ClientVersionName(ClientVersion client_version)
{
switch (client_version) {
case ClientVersion::Unknown:
return "Unknown Version";
case ClientVersion::Client62:
return "Client 6.2";
case ClientVersion::Titanium:
return "Titanium";
case ClientVersion::SoF:
return "SoF";
case ClientVersion::SoD:
return "SoD";
case ClientVersion::UF:
return "UF";
case ClientVersion::RoF:
return "RoF";
case ClientVersion::RoF2:
return "RoF2";
default:
return "Invalid Version";
};
}
uint32 EQEmu::versions::ConvertClientVersionToClientVersionBit(ClientVersion client_version)
{
switch (client_version) {
case ClientVersion::Unknown:
case ClientVersion::Client62:
return bit_Unknown;
case ClientVersion::Titanium:
return bit_Titanium;
case ClientVersion::SoF:
return bit_SoF;
case ClientVersion::SoD:
return bit_SoD;
case ClientVersion::UF:
return bit_UF;
case ClientVersion::RoF:
return bit_RoF;
case ClientVersion::RoF2:
return bit_RoF2;
default:
return bit_Unknown;
}
}
EQEmu::versions::ClientVersion EQEmu::versions::ConvertClientVersionBitToClientVersion(uint32 client_version_bit)
{
switch (client_version_bit) {
case (uint32)static_cast<unsigned int>(ClientVersion::Unknown) :
case ((uint32)1 << (static_cast<unsigned int>(ClientVersion::Client62) - 1)) :
return ClientVersion::Unknown;
case ((uint32)1 << (static_cast<unsigned int>(ClientVersion::Titanium) - 1)) :
return ClientVersion::Titanium;
case ((uint32)1 << (static_cast<unsigned int>(ClientVersion::SoF) - 1)) :
return ClientVersion::SoF;
case ((uint32)1 << (static_cast<unsigned int>(ClientVersion::SoD) - 1)) :
return ClientVersion::SoD;
case ((uint32)1 << (static_cast<unsigned int>(ClientVersion::UF) - 1)) :
return ClientVersion::UF;
case ((uint32)1 << (static_cast<unsigned int>(ClientVersion::RoF) - 1)) :
return ClientVersion::RoF;
case ((uint32)1 << (static_cast<unsigned int>(ClientVersion::RoF2) - 1)) :
return ClientVersion::RoF2;
default:
return ClientVersion::Unknown;
}
}
uint32 EQEmu::versions::ConvertClientVersionToExpansion(ClientVersion client_version)
{
switch (client_version) {
case ClientVersion::Unknown:
case ClientVersion::Client62:
case ClientVersion::Titanium:
return 0x000007FFU;
case ClientVersion::SoF:
return 0x00007FFFU;
case ClientVersion::SoD:
return 0x0000FFFFU;
case ClientVersion::UF:
return 0x0001FFFFU;
case ClientVersion::RoF:
case ClientVersion::RoF2:
return 0x000FFFFFU;
default:
return 0;
}
}
+27 -20
View File
@@ -1,5 +1,6 @@
/* EQEMu: Everquest Server Emulator
Copyright (C) 2001-2014 EQEMu Development Team (http://eqemulator.net)
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
@@ -13,36 +14,42 @@
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef COMMON_DATA_VERIFICATION_H
#define COMMON_DATA_VERIFICATION_H
#include <algorithm>
namespace EQEmu
{
template <typename T>
T Clamp(const T& value, const T& lower, const T& upper) {
return std::max(lower, std::min(value, upper));
}
template <typename T>
T Clamp(const T& value, const T& lower, const T& upper) {
return std::max(lower, std::min(value, upper));
}
template <typename T>
T ClampLower(const T& value, const T& lower) {
return std::max(lower, value);
}
template <typename T>
T ClampLower(const T& value, const T& lower) {
return std::max(lower, value);
}
template <typename T>
T ClampUpper(const T& value, const T& upper) {
return std::min(value, upper);
}
template <typename T>
T ClampUpper(const T& value, const T& upper) {
return std::min(value, upper);
}
template <typename T>
bool ValueWithin(const T& value, const T& lower, const T& upper) {
return value >= lower && value <= upper;
}
template <typename T>
bool ValueWithin(const T& value, const T& lower, const T& upper) {
return value >= lower && value <= upper;
}
template <typename T1, typename T2, typename T3>
bool ValueWithin(const T1& value, const T2& lower, const T3& upper) {
return value >= (T1)lower && value <= (T1)upper;
}
}
} /*EQEmu*/
#endif
#endif /*COMMON_DATA_VERIFICATION_H*/
+15 -3
View File
@@ -627,9 +627,9 @@ bool Database::SaveCharacterCreate(uint32 character_id, uint32 account_id, Playe
/* Save Bind Points */
query = StringFormat("REPLACE INTO `character_bind` (id, zone_id, instance_id, x, y, z, heading, slot)"
" VALUES (%u, %u, %u, %f, %f, %f, %f, %i), "
"(%u, %u, %u, %f, %f, %f, %f, %i), ",
"(%u, %u, %u, %f, %f, %f, %f, %i), ",
"(%u, %u, %u, %f, %f, %f, %f, %i), ",
"(%u, %u, %u, %f, %f, %f, %f, %i), "
"(%u, %u, %u, %f, %f, %f, %f, %i), "
"(%u, %u, %u, %f, %f, %f, %f, %i), "
"(%u, %u, %u, %f, %f, %f, %f, %i)",
character_id, pp->binds[0].zoneId, 0, pp->binds[0].x, pp->binds[0].y, pp->binds[0].z, pp->binds[0].heading, 0,
character_id, pp->binds[1].zoneId, 0, pp->binds[1].x, pp->binds[1].y, pp->binds[1].z, pp->binds[1].heading, 1,
@@ -2136,3 +2136,15 @@ 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);
}
+2 -11
View File
@@ -79,17 +79,6 @@ struct VarCache_Struct {
class PTimerList;
#ifdef _WINDOWS
#if _MSC_VER > 1700 // greater than 2012 (2013+)
# define _ISNAN_(a) std::isnan(a)
#else
# include <float.h>
# define _ISNAN_(a) _isnan(a)
#endif
#else
# define _ISNAN_(a) std::isnan(a)
#endif
class Database : public DBcore {
public:
Database();
@@ -186,6 +175,8 @@ public:
void GetAccountFromID(uint32 id, char* oAccountName, int16* oStatus);
void SetAgreementFlag(uint32 acctid);
int GetIPExemption(std::string account_ip);
/* Groups */
+12 -25
View File
@@ -186,7 +186,7 @@ namespace Convert {
/*002*/ uint32 HP;
/*006*/ uint32 Mana;
/*010*/ Convert::SpellBuff_Struct Buffs[BUFF_COUNT];
/*510*/ uint32 Items[EQEmu::legacy::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::legacy::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::legacy::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,31 +472,18 @@ bool Database::CheckDatabaseConversions() {
CheckDatabaseConvertPPDeblob();
CheckDatabaseConvertCorpseDeblob();
/* Fetch Automatic Upgrade Script */
if (!std::ifstream("eqemu_update.pl")){
/* Fetch EQEmu Server script */
if (!std::ifstream("eqemu_server.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_update.pl'); if ($response->is_success){ open(FILE, '> eqemu_update.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_server.pl'); if ($response->is_success){ open(FILE, '> eqemu_server.pl'); print FILE $response->decoded_content; close(FILE); }\"");
#else
system("wget --no-check-certificate -O eqemu_update.pl https://raw.githubusercontent.com/EQEmu/Server/master/utils/scripts/eqemu_update.pl");
system("wget --no-check-certificate -O eqemu_server.pl https://raw.githubusercontent.com/EQEmu/Server/master/utils/scripts/eqemu_server.pl");
#endif
}
/*
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");
/* Run EQEmu Server script (Checks for database updates) */
system("perl eqemu_server.pl ran_from_world");
return true;
}
@@ -1340,7 +1327,7 @@ bool Database::CheckDatabaseConvertPPDeblob(){
if (rquery != ""){ results = QueryDatabase(rquery); }
/* Run Bind Home Convert */
if (pp->binds[4].zoneId < 999 && !_ISNAN_(pp->binds[4].x) && !_ISNAN_(pp->binds[4].y) && !_ISNAN_(pp->binds[4].z) && !_ISNAN_(pp->binds[4].heading)) {
if (pp->binds[4].zoneId < 999 && !std::isnan(pp->binds[4].x) && !std::isnan(pp->binds[4].y) && !std::isnan(pp->binds[4].z) && !std::isnan(pp->binds[4].heading)) {
rquery = StringFormat("REPLACE INTO `character_bind` (id, zone_id, instance_id, x, y, z, heading, is_home)"
" VALUES (%u, %u, %u, %f, %f, %f, %f, 1)",
character_id, pp->binds[4].zoneId, 0, pp->binds[4].x, pp->binds[4].y, pp->binds[4].z, pp->binds[4].heading);
@@ -1348,7 +1335,7 @@ bool Database::CheckDatabaseConvertPPDeblob(){
}
/* Run Bind Convert */
if (pp->binds[0].zoneId < 999 && !_ISNAN_(pp->binds[0].x) && !_ISNAN_(pp->binds[0].y) && !_ISNAN_(pp->binds[0].z) && !_ISNAN_(pp->binds[0].heading)) {
if (pp->binds[0].zoneId < 999 && !std::isnan(pp->binds[0].x) && !std::isnan(pp->binds[0].y) && !std::isnan(pp->binds[0].z) && !std::isnan(pp->binds[0].heading)) {
rquery = StringFormat("REPLACE INTO `character_bind` (id, zone_id, instance_id, x, y, z, heading, is_home)"
" VALUES (%u, %u, %u, %f, %f, %f, %f, 0)",
character_id, pp->binds[0].zoneId, 0, pp->binds[0].x, pp->binds[0].y, pp->binds[0].z, pp->binds[0].heading);
@@ -1416,7 +1403,7 @@ bool Database::CheckDatabaseConvertPPDeblob(){
if (rquery != ""){ results = QueryDatabase(rquery); }
/* Run Material Color Convert */
first_entry = 0; rquery = "";
for (i = 0; i < EQEmu::legacy::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);
+21 -3
View File
@@ -22,9 +22,7 @@
#include "eq_limits.h"
#include "emu_legacy.h"
#include "inventory_version.h"
//#include "deity.h"
//#include "say_link.h"
#include "emu_versions.h"
#include <string>
@@ -46,6 +44,26 @@ namespace EQEmu
const size_t SayLinkBodySize = RoF2::constants::SayLinkBodySize;
} /*constants*/
enum class CastingSlot : uint32 {
Gem1 = 0,
Gem2 = 1,
Gem3 = 2,
Gem4 = 3,
Gem5 = 4,
Gem6 = 5,
Gem7 = 6,
Gem8 = 7,
Gem9 = 8,
Gem10 = 9,
Gem11 = 10,
Gem12 = 11,
MaxGems = 12,
Ability = 20, // HT/LoH for Tit
PotionBelt = 21, // Tit uses a different slot for PB
Item = 22,
Discipline = 23,
AltAbility = 0xFF
};
} /*EQEmu*/
-19
View File
@@ -163,20 +163,6 @@ namespace EQEmu
SlotCount
};
enum MaterialSlots : uint8 {
MaterialHead = 0,
MaterialChest,
MaterialArms,
MaterialWrist,
MaterialHands,
MaterialLegs, // 5
MaterialFeet,
MaterialPrimary,
MaterialSecondary,
MaterialCount,
MaterialInvalid = 255
};
// 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 = SlotCount;
static const uint16 TYPE_BANK_SIZE = 24;
@@ -251,11 +237,6 @@ namespace EQEmu
static const int16 CORPSE_BEGIN = 22;
//static const int16 CORPSE_END = RoF::consts::CORPSE_END; // not ready for use
static const int16 MATERIAL_BEGIN = MaterialHead;
static const int16 MATERIAL_END = MaterialSecondary;
static const int16 MATERIAL_TINT_END = MaterialFeet;
static const int16 MATERIAL_SIZE = MaterialCount;
// 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;
+2 -2
View File
@@ -1,4 +1,4 @@
/* EQEMu: Everquest Server Emulator
/* EQEMu: Everquest Server Emulator
Copyright (C) 2001-2016 EQEMu Development Team (http://eqemulator.net)
@@ -10,7 +10,7 @@
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.
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
+58 -10
View File
@@ -1,4 +1,4 @@
/* EQEMu: Everquest Server Emulator
/* EQEMu: Everquest Server Emulator
Copyright (C) 2001-2016 EQEMu Development Team (http://eqemulator.net)
@@ -10,7 +10,7 @@
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.
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
@@ -27,29 +27,77 @@
namespace EntityLimits
{
namespace npc {
namespace NPC {
enum : int { Invalid = -1, Null, Safety };
enum : bool { False = false, True = true };
}
namespace merc {
const size_t InvTypeTradeSize = 4;
} /*NPC*/
namespace NPCMerchant {
enum : int { Invalid = -1, Null, Safety };
enum : bool { False = false, True = true };
}
namespace bot {
const size_t InvTypeTradeSize = 4;
} /*NPCMerchant*/
namespace Merc {
enum : int { Invalid = -1, Null, Safety };
enum : bool { False = false, True = true };
}
namespace pet {
const size_t InvTypeTradeSize = 4;
} /*Merc*/
namespace Bot {
enum : int { Invalid = -1, Null, Safety };
enum : bool { False = false, True = true };
}
const size_t InvTypeTradeSize = 8;
} /*Bot*/
namespace ClientPet {
enum : int { Invalid = -1, Null, Safety };
enum : bool { False = false, True = true };
const size_t InvTypeTradeSize = 4;
} /*Pet*/
namespace NPCPet {
enum : int { Invalid = -1, Null, Safety };
enum : bool { False = false, True = true };
const size_t InvTypeTradeSize = 4;
} /*Pet*/
namespace MercPet {
enum : int { Invalid = -1, Null, Safety };
enum : bool { False = false, True = true };
const size_t InvTypeTradeSize = 4;
} /*Pet*/
namespace BotPet {
enum : int { Invalid = -1, Null, Safety };
enum : bool { False = false, True = true };
const size_t InvTypeTradeSize = 4;
} /*Pet*/
}; /*EntityLimits*/
+2
View File
@@ -64,6 +64,7 @@ N(OP_BuffRemoveRequest),
N(OP_Bug),
N(OP_CameraEffect),
N(OP_Camp),
N(OP_CancelSneakHide),
N(OP_CancelTask),
N(OP_CancelTrade),
N(OP_CastSpell),
@@ -288,6 +289,7 @@ N(OP_LFGuild),
N(OP_LFPCommand),
N(OP_LFPGetMatchesRequest),
N(OP_LFPGetMatchesResponse),
N(OP_LinkedReuse),
N(OP_LoadSpellSet),
N(OP_LocInfo),
N(OP_LockoutTimerInfo),
+370
View File
@@ -0,0 +1,370 @@
/* 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 "emu_versions.h"
bool EQEmu::versions::IsValidClientVersion(ClientVersion client_version)
{
if (client_version <= ClientVersion::Unknown || client_version > LastClientVersion)
return false;
return true;
}
EQEmu::versions::ClientVersion EQEmu::versions::ValidateClientVersion(ClientVersion client_version)
{
if (client_version <= ClientVersion::Unknown || client_version > LastClientVersion)
return ClientVersion::Unknown;
return client_version;
}
const char* EQEmu::versions::ClientVersionName(ClientVersion client_version)
{
switch (client_version) {
case ClientVersion::Unknown:
return "Unknown Version";
case ClientVersion::Client62:
return "Client 6.2";
case ClientVersion::Titanium:
return "Titanium";
case ClientVersion::SoF:
return "SoF";
case ClientVersion::SoD:
return "SoD";
case ClientVersion::UF:
return "UF";
case ClientVersion::RoF:
return "RoF";
case ClientVersion::RoF2:
return "RoF2";
default:
return "Invalid Version";
};
}
uint32 EQEmu::versions::ConvertClientVersionToClientVersionBit(ClientVersion client_version)
{
switch (client_version) {
case ClientVersion::Unknown:
case ClientVersion::Client62:
return bit_Unknown;
case ClientVersion::Titanium:
return bit_Titanium;
case ClientVersion::SoF:
return bit_SoF;
case ClientVersion::SoD:
return bit_SoD;
case ClientVersion::UF:
return bit_UF;
case ClientVersion::RoF:
return bit_RoF;
case ClientVersion::RoF2:
return bit_RoF2;
default:
return bit_Unknown;
}
}
EQEmu::versions::ClientVersion EQEmu::versions::ConvertClientVersionBitToClientVersion(uint32 client_version_bit)
{
switch (client_version_bit) {
case (uint32)static_cast<unsigned int>(ClientVersion::Unknown) :
case ((uint32)1 << (static_cast<unsigned int>(ClientVersion::Client62) - 1)) :
return ClientVersion::Unknown;
case ((uint32)1 << (static_cast<unsigned int>(ClientVersion::Titanium) - 1)) :
return ClientVersion::Titanium;
case ((uint32)1 << (static_cast<unsigned int>(ClientVersion::SoF) - 1)) :
return ClientVersion::SoF;
case ((uint32)1 << (static_cast<unsigned int>(ClientVersion::SoD) - 1)) :
return ClientVersion::SoD;
case ((uint32)1 << (static_cast<unsigned int>(ClientVersion::UF) - 1)) :
return ClientVersion::UF;
case ((uint32)1 << (static_cast<unsigned int>(ClientVersion::RoF) - 1)) :
return ClientVersion::RoF;
case ((uint32)1 << (static_cast<unsigned int>(ClientVersion::RoF2) - 1)) :
return ClientVersion::RoF2;
default:
return ClientVersion::Unknown;
}
}
uint32 EQEmu::versions::ConvertClientVersionToExpansion(ClientVersion client_version)
{
switch (client_version) {
case ClientVersion::Unknown:
case ClientVersion::Client62:
case ClientVersion::Titanium:
return 0x000007FFU;
case ClientVersion::SoF:
return 0x00007FFFU;
case ClientVersion::SoD:
return 0x0000FFFFU;
case ClientVersion::UF:
return 0x0001FFFFU;
case ClientVersion::RoF:
case ClientVersion::RoF2:
return 0x000FFFFFU;
default:
return 0;
}
}
bool EQEmu::versions::IsValidInventoryVersion(InventoryVersion inventory_version)
{
if (inventory_version <= InventoryVersion::Unknown || inventory_version > LastInventoryVersion)
return false;
return true;
}
bool EQEmu::versions::IsValidPCInventoryVersion(InventoryVersion inventory_version)
{
if (inventory_version <= InventoryVersion::Unknown || inventory_version > LastPCInventoryVersion)
return false;
return true;
}
bool EQEmu::versions::IsValidNonPCInventoryVersion(InventoryVersion inventory_version)
{
if (inventory_version <= LastPCInventoryVersion || inventory_version > LastNonPCInventoryVersion)
return false;
return true;
}
bool EQEmu::versions::IsValidOfflinePCInventoryVersion(InventoryVersion inventory_version)
{
if (inventory_version <= LastNonPCInventoryVersion || inventory_version > LastOfflinePCInventoryVersion)
return false;
return true;
}
EQEmu::versions::InventoryVersion EQEmu::versions::ValidateInventoryVersion(InventoryVersion inventory_version)
{
if (inventory_version <= InventoryVersion::Unknown || inventory_version > LastInventoryVersion)
return InventoryVersion::Unknown;
return inventory_version;
}
EQEmu::versions::InventoryVersion EQEmu::versions::ValidatePCInventoryVersion(InventoryVersion inventory_version)
{
if (inventory_version <= InventoryVersion::Unknown || inventory_version > LastPCInventoryVersion)
return InventoryVersion::Unknown;
return inventory_version;
}
EQEmu::versions::InventoryVersion EQEmu::versions::ValidateNonPCInventoryVersion(InventoryVersion inventory_version)
{
if (inventory_version <= LastPCInventoryVersion || inventory_version > LastNonPCInventoryVersion)
return InventoryVersion::Unknown;
return inventory_version;
}
EQEmu::versions::InventoryVersion EQEmu::versions::ValidateOfflinePCInventoryVersion(InventoryVersion inventory_version)
{
if (inventory_version <= LastNonPCInventoryVersion || inventory_version > LastOfflinePCInventoryVersion)
return InventoryVersion::Unknown;
return inventory_version;
}
const char* EQEmu::versions::InventoryVersionName(InventoryVersion inventory_version)
{
switch (inventory_version) {
case InventoryVersion::Unknown:
return "Unknown Version";
case InventoryVersion::Client62:
return "Client 6.2";
case InventoryVersion::Titanium:
return "Titanium";
case InventoryVersion::SoF:
return "SoF";
case InventoryVersion::SoD:
return "SoD";
case InventoryVersion::UF:
return "UF";
case InventoryVersion::RoF:
return "RoF";
case InventoryVersion::RoF2:
return "RoF2";
case InventoryVersion::NPC:
return "NPC";
case InventoryVersion::NPCMerchant:
return "NPC Merchant";
case InventoryVersion::Merc:
return "Merc";
case InventoryVersion::Bot:
return "Bot";
case InventoryVersion::ClientPet:
return "Client Pet";
case InventoryVersion::NPCPet:
return "NPC Pet";
case InventoryVersion::MercPet:
return "Merc Pet";
case InventoryVersion::BotPet:
return "Bot Pet";
case InventoryVersion::OfflineTitanium:
return "Offline Titanium";
case InventoryVersion::OfflineSoF:
return "Offline SoF";
case InventoryVersion::OfflineSoD:
return "Offline SoD";
case InventoryVersion::OfflineUF:
return "Offline UF";
case InventoryVersion::OfflineRoF:
return "Offline RoF";
case InventoryVersion::OfflineRoF2:
return "Offline RoF2";
default:
return "Invalid Version";
};
}
EQEmu::versions::ClientVersion EQEmu::versions::ConvertInventoryVersionToClientVersion(InventoryVersion inventory_version)
{
switch (inventory_version) {
case InventoryVersion::Unknown:
case InventoryVersion::Client62:
return ClientVersion::Unknown;
case InventoryVersion::Titanium:
return ClientVersion::Titanium;
case InventoryVersion::SoF:
return ClientVersion::SoF;
case InventoryVersion::SoD:
return ClientVersion::SoD;
case InventoryVersion::UF:
return ClientVersion::UF;
case InventoryVersion::RoF:
return ClientVersion::RoF;
case InventoryVersion::RoF2:
return ClientVersion::RoF2;
default:
return ClientVersion::Unknown;
}
}
EQEmu::versions::InventoryVersion EQEmu::versions::ConvertClientVersionToInventoryVersion(ClientVersion client_version)
{
switch (client_version) {
case ClientVersion::Unknown:
case ClientVersion::Client62:
return InventoryVersion::Unknown;
case ClientVersion::Titanium:
return InventoryVersion::Titanium;
case ClientVersion::SoF:
return InventoryVersion::SoF;
case ClientVersion::SoD:
return InventoryVersion::SoD;
case ClientVersion::UF:
return InventoryVersion::UF;
case ClientVersion::RoF:
return InventoryVersion::RoF;
case ClientVersion::RoF2:
return InventoryVersion::RoF2;
default:
return InventoryVersion::Unknown;
}
}
EQEmu::versions::InventoryVersion EQEmu::versions::ConvertPCInventoryVersionToOfflinePCInventoryVersion(InventoryVersion inventory_version)
{
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 InventoryVersion::Unknown;
}
}
EQEmu::versions::InventoryVersion EQEmu::versions::ConvertOfflinePCInventoryVersionToPCInventoryVersion(InventoryVersion inventory_version)
{
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 InventoryVersion::Unknown;
}
}
EQEmu::versions::ClientVersion EQEmu::versions::ConvertOfflinePCInventoryVersionToClientVersion(InventoryVersion inventory_version)
{
switch (inventory_version) {
case InventoryVersion::OfflineTitanium:
return ClientVersion::Titanium;
case InventoryVersion::OfflineSoF:
return ClientVersion::SoF;
case InventoryVersion::OfflineSoD:
return ClientVersion::SoD;
case InventoryVersion::OfflineUF:
return ClientVersion::UF;
case InventoryVersion::OfflineRoF:
return ClientVersion::RoF;
case InventoryVersion::OfflineRoF2:
return ClientVersion::RoF2;
default:
return ClientVersion::Unknown;
}
}
EQEmu::versions::InventoryVersion EQEmu::versions::ConvertClientVersionToOfflinePCInventoryVersion(ClientVersion client_version)
{
switch (client_version) {
case ClientVersion::Titanium:
return InventoryVersion::OfflineTitanium;
case ClientVersion::SoF:
return InventoryVersion::OfflineSoF;
case ClientVersion::SoD:
return InventoryVersion::OfflineSoD;
case ClientVersion::UF:
return InventoryVersion::OfflineUF;
case ClientVersion::RoF:
return InventoryVersion::OfflineRoF;
case ClientVersion::RoF2:
return InventoryVersion::OfflineRoF2;
default:
return InventoryVersion::Unknown;
}
}
@@ -17,8 +17,8 @@
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef COMMON_CLIENT_VERSION_H
#define COMMON_CLIENT_VERSION_H
#ifndef COMMON_EMU_VERSIONS_H
#define COMMON_EMU_VERSIONS_H
#include "types.h"
@@ -61,8 +61,8 @@ namespace EQEmu
bit_AllClients = 0xFFFFFFFF
};
static const ClientVersion LastClientVersion = ClientVersion::RoF2;
static const size_t ClientVersionCount = (static_cast<size_t>(LastClientVersion) + 1);
const ClientVersion LastClientVersion = ClientVersion::RoF2;
const size_t ClientVersionCount = (static_cast<size_t>(LastClientVersion) + 1);
extern bool IsValidClientVersion(ClientVersion client_version);
extern ClientVersion ValidateClientVersion(ClientVersion client_version);
@@ -70,9 +70,61 @@ namespace EQEmu
extern uint32 ConvertClientVersionToClientVersionBit(ClientVersion client_version);
extern ClientVersion ConvertClientVersionBitToClientVersion(uint32 client_version_bit);
extern uint32 ConvertClientVersionToExpansion(ClientVersion client_version);
} /*versions*/
namespace versions {
enum class InventoryVersion {
Unknown = 0,
Client62,
Titanium,
SoF,
SoD,
UF,
RoF,
RoF2,
NPC,
NPCMerchant,
Merc,
Bot,
ClientPet,
NPCPet,
MercPet,
BotPet,
OfflineTitanium,
OfflineSoF,
OfflineSoD,
OfflineUF,
OfflineRoF,
OfflineRoF2
};
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);
extern bool IsValidInventoryVersion(InventoryVersion inventory_version);
extern bool IsValidPCInventoryVersion(InventoryVersion inventory_version);
extern bool IsValidNonPCInventoryVersion(InventoryVersion inventory_version);
extern bool IsValidOfflinePCInventoryVersion(InventoryVersion inventory_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);
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*/
} /*EQEmu*/
#endif /*COMMON_CLIENT_VERSION_H*/
#endif /*COMMON_EMU_VERSIONS_H*/
-1
View File
@@ -516,7 +516,6 @@ static const uint8 SkillDamageTypes[EQEmu::skills::HIGHEST_SKILL + 1] = // chang
*/
#define INVALID_INDEX -1
#define NOT_USED 0
#define NO_ITEM 0
// yes..these are redundant... but, they help to identify and define what is actually being performed
+344 -484
View File
@@ -1,4 +1,4 @@
/* EQEMu: Everquest Server Emulator
/* EQEMu: Everquest Server Emulator
Copyright (C) 2001-2016 EQEMu Development Team (http://eqemulator.net)
@@ -10,7 +10,7 @@
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.
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
@@ -21,501 +21,361 @@
#include "emu_limits.h"
size_t EQEmu::constants::CharacterCreationLimit(versions::ClientVersion client_version)
static const EQEmu::constants::LookupEntry constants_lookup_entries[EQEmu::versions::ClientVersionCount] =
{
static const size_t local[versions::ClientVersionCount] = {
ClientUnknown::Null,
Client62::Null,
Titanium::constants::CharacterCreationLimit,
SoF::constants::CharacterCreationLimit,
SoD::constants::CharacterCreationLimit,
UF::constants::CharacterCreationLimit,
RoF::constants::CharacterCreationLimit,
{ // Unknown
ClientUnknown::Null
},
{ // Client62
Client62::Null
},
{ // Titanium
Titanium::constants::CharacterCreationLimit
},
{ // SoF
SoF::constants::CharacterCreationLimit
},
{ // SoD
SoD::constants::CharacterCreationLimit
},
{ // UF
UF::constants::CharacterCreationLimit
},
{ // RoF
RoF::constants::CharacterCreationLimit
},
{ // RoF2
RoF2::constants::CharacterCreationLimit
};
}
};
return local[static_cast<size_t>(versions::ValidateClientVersion(client_version))];
}
uint16 EQEmu::inventory::InventoryTypeSize(versions::InventoryVersion inventory_version, int16 inv_type)
const EQEmu::constants::LookupEntry* EQEmu::constants::Lookup(versions::ClientVersion client_version)
{
static const uint16 local[legacy::TypeCount][versions::InventoryVersionCount] = {
{ // local[TypePossessions]
ClientUnknown::Null,
Client62::Null,
legacy::TYPE_POSSESSIONS_SIZE,
legacy::TYPE_POSSESSIONS_SIZE,
legacy::TYPE_POSSESSIONS_SIZE,
legacy::TYPE_POSSESSIONS_SIZE,
legacy::TYPE_POSSESSIONS_SIZE,
legacy::TYPE_POSSESSIONS_SIZE,
legacy::TYPE_POSSESSIONS_SIZE,
legacy::TYPE_POSSESSIONS_SIZE,
legacy::TYPE_POSSESSIONS_SIZE,
legacy::TYPE_POSSESSIONS_SIZE
},
{ // local[TypeBank]
ClientUnknown::Null,
Client62::Null,
Titanium::invtype::InvTypeBankSize,
legacy::TYPE_BANK_SIZE,
legacy::TYPE_BANK_SIZE,
legacy::TYPE_BANK_SIZE,
legacy::TYPE_BANK_SIZE,
legacy::TYPE_BANK_SIZE,
EntityLimits::npc::Null,
EntityLimits::merc::Null,
EntityLimits::bot::Null,
EntityLimits::pet::Null
},
{ // local[TypeSharedBank]
ClientUnknown::Null,
Client62::Null,
legacy::TYPE_SHARED_BANK_SIZE,
legacy::TYPE_SHARED_BANK_SIZE,
legacy::TYPE_SHARED_BANK_SIZE,
legacy::TYPE_SHARED_BANK_SIZE,
legacy::TYPE_SHARED_BANK_SIZE,
legacy::TYPE_SHARED_BANK_SIZE,
EntityLimits::npc::Null,
EntityLimits::merc::Null,
EntityLimits::bot::Null,
EntityLimits::pet::Null
},
{ // local[TypeTrade]
ClientUnknown::Null,
Client62::Null,
legacy::TYPE_TRADE_SIZE,
legacy::TYPE_TRADE_SIZE,
legacy::TYPE_TRADE_SIZE,
legacy::TYPE_TRADE_SIZE,
legacy::TYPE_TRADE_SIZE,
legacy::TYPE_TRADE_SIZE,
4,
4,
legacy::TYPE_TRADE_SIZE, // client thinks this is another client
4
},
{ // local[TypeWorld]
ClientUnknown::Null,
Client62::Null,
legacy::TYPE_WORLD_SIZE,
legacy::TYPE_WORLD_SIZE,
legacy::TYPE_WORLD_SIZE,
legacy::TYPE_WORLD_SIZE,
legacy::TYPE_WORLD_SIZE,
legacy::TYPE_WORLD_SIZE,
EntityLimits::npc::Null,
EntityLimits::merc::Null,
EntityLimits::bot::Null,
EntityLimits::pet::Null
},
{ // local[TypeLimbo]
ClientUnknown::Null,
Client62::Null,
legacy::TYPE_LIMBO_SIZE,
legacy::TYPE_LIMBO_SIZE,
legacy::TYPE_LIMBO_SIZE,
legacy::TYPE_LIMBO_SIZE,
legacy::TYPE_LIMBO_SIZE,
legacy::TYPE_LIMBO_SIZE,
EntityLimits::npc::Null,
EntityLimits::merc::Null,
EntityLimits::bot::Null,
EntityLimits::pet::Null
},
{ // local[TypeTribute]
ClientUnknown::Null,
Client62::Null,
legacy::TYPE_TRIBUTE_SIZE,
legacy::TYPE_TRIBUTE_SIZE,
legacy::TYPE_TRIBUTE_SIZE,
legacy::TYPE_TRIBUTE_SIZE,
legacy::TYPE_TRIBUTE_SIZE,
legacy::TYPE_TRIBUTE_SIZE,
EntityLimits::npc::Null,
EntityLimits::merc::Null,
EntityLimits::bot::Null,
EntityLimits::pet::Null
},
{ // local[TypeTrophyTribute]
ClientUnknown::Null,
Client62::Null,
Titanium::Null,
SoF::Null,
SoD::Null,
UF::Null,
legacy::TYPE_TROPHY_TRIBUTE_SIZE,
legacy::TYPE_TROPHY_TRIBUTE_SIZE,
EntityLimits::npc::Null,
EntityLimits::merc::Null,
EntityLimits::bot::Null,
EntityLimits::pet::Null
},
{ // local[TypeGuildTribute]
ClientUnknown::Null,
Client62::Null,
Titanium::Null,
SoF::Null,
SoD::Null,
UF::Null,
legacy::TYPE_GUILD_TRIBUTE_SIZE,
legacy::TYPE_GUILD_TRIBUTE_SIZE,
EntityLimits::npc::Null,
EntityLimits::merc::Null,
EntityLimits::bot::Null,
EntityLimits::pet::Null
},
{ // local[TypeMerchant]
ClientUnknown::Null,
Client62::Null,
Titanium::Null,
SoF::Null,
SoD::Null,
UF::Null,
legacy::TYPE_MERCHANT_SIZE,
legacy::TYPE_MERCHANT_SIZE,
EntityLimits::npc::Null,
EntityLimits::merc::Null,
EntityLimits::bot::Null,
EntityLimits::pet::Null
},
{ // local[TypeDeleted]
ClientUnknown::Null,
Client62::Null,
Titanium::Null,
SoF::Null,
SoD::Null,
UF::Null,
legacy::TYPE_DELETED_SIZE,
legacy::TYPE_DELETED_SIZE,
EntityLimits::npc::Null,
EntityLimits::merc::Null,
EntityLimits::bot::Null,
EntityLimits::pet::Null
},
{ // local[TypeCorpse]
ClientUnknown::Null,
Client62::Null,
Titanium::invtype::InvTypeCorpseSize,
SoF::invtype::InvTypeCorpseSize,
SoD::invtype::InvTypeCorpseSize,
UF::invtype::InvTypeCorpseSize,
RoF::invtype::InvTypeCorpseSize,
RoF2::invtype::InvTypeCorpseSize,
EntityLimits::npc::Null,
EntityLimits::merc::Null,
EntityLimits::bot::Null,
EntityLimits::pet::Null
},
{ // local[TypeBazaar]
ClientUnknown::Null,
Client62::Null,
legacy::TYPE_BAZAAR_SIZE,
legacy::TYPE_BAZAAR_SIZE,
legacy::TYPE_BAZAAR_SIZE,
legacy::TYPE_BAZAAR_SIZE,
legacy::TYPE_BAZAAR_SIZE,
legacy::TYPE_BAZAAR_SIZE,
EntityLimits::npc::Null,
EntityLimits::merc::Null,
EntityLimits::bot::Null,
EntityLimits::pet::Null
},
{ // local[TypeInspect]
ClientUnknown::Null,
Client62::Null,
Titanium::invtype::InvTypeInspectSize,
SoF::invtype::InvTypeInspectSize,
SoD::invtype::InvTypeInspectSize,
UF::invtype::InvTypeInspectSize,
RoF::invtype::InvTypeInspectSize,
RoF2::invtype::InvTypeInspectSize,
EntityLimits::npc::Null,
EntityLimits::merc::Null,
EntityLimits::bot::Null,
EntityLimits::pet::Null
},
{ // local[TypeRealEstate]
ClientUnknown::Null,
Client62::Null,
Titanium::Null,
SoF::Null,
SoD::Null,
UF::Null,
legacy::TYPE_REAL_ESTATE_SIZE,
legacy::TYPE_REAL_ESTATE_SIZE,
EntityLimits::npc::Null,
EntityLimits::merc::Null,
EntityLimits::bot::Null,
EntityLimits::pet::Null
},
{ // local[TypeViewMODPC]
ClientUnknown::Null,
Client62::Null,
Titanium::Null,
SoF::Null,
SoD::Null,
UF::Null,
legacy::TYPE_VIEW_MOD_PC_SIZE,
legacy::TYPE_VIEW_MOD_PC_SIZE,
EntityLimits::npc::Null,
EntityLimits::merc::Null,
EntityLimits::bot::Null,
EntityLimits::pet::Null
},
{ // local[TypeViewMODBank]
ClientUnknown::Null,
Client62::Null,
Titanium::Null,
SoF::Null,
SoD::Null,
UF::Null,
legacy::TYPE_VIEW_MOD_BANK_SIZE,
legacy::TYPE_VIEW_MOD_BANK_SIZE,
EntityLimits::npc::Null,
EntityLimits::merc::Null,
EntityLimits::bot::Null,
EntityLimits::pet::Null
},
{ // local[TypeViewMODSharedBank]
ClientUnknown::Null,
Client62::Null,
Titanium::Null,
SoF::Null,
SoD::Null,
UF::Null,
legacy::TYPE_VIEW_MOD_SHARED_BANK_SIZE,
legacy::TYPE_VIEW_MOD_SHARED_BANK_SIZE,
EntityLimits::npc::Null,
EntityLimits::merc::Null,
EntityLimits::bot::Null,
EntityLimits::pet::Null
},
{ // local[TypeViewMODLimbo]
ClientUnknown::Null,
Client62::Null,
Titanium::Null,
SoF::Null,
SoD::Null,
UF::Null,
legacy::TYPE_VIEW_MOD_LIMBO_SIZE,
legacy::TYPE_VIEW_MOD_LIMBO_SIZE,
EntityLimits::npc::Null,
EntityLimits::merc::Null,
EntityLimits::bot::Null,
EntityLimits::pet::Null
},
{ // local[TypeAltStorage]
ClientUnknown::Null,
Client62::Null,
Titanium::Null,
SoF::Null,
SoD::Null,
UF::Null,
legacy::TYPE_ALT_STORAGE_SIZE,
legacy::TYPE_ALT_STORAGE_SIZE,
EntityLimits::npc::Null,
EntityLimits::merc::Null,
EntityLimits::bot::Null,
EntityLimits::pet::Null
},
{ // local[TypeArchived]
ClientUnknown::Null,
Client62::Null,
Titanium::Null,
SoF::Null,
SoD::Null,
UF::Null,
legacy::TYPE_ARCHIVED_SIZE,
legacy::TYPE_ARCHIVED_SIZE,
EntityLimits::npc::Null,
EntityLimits::merc::Null,
EntityLimits::bot::Null,
EntityLimits::pet::Null
},
{ // local[TypeMail]
ClientUnknown::Null,
Client62::Null,
Titanium::Null,
SoF::Null,
SoD::Null,
UF::Null,
legacy::TYPE_MAIL_SIZE,
legacy::TYPE_MAIL_SIZE,
EntityLimits::npc::Null,
EntityLimits::merc::Null,
EntityLimits::bot::Null,
EntityLimits::pet::Null
},
{ // local[TypeGuildTrophyTribute]
ClientUnknown::Null,
Client62::Null,
Titanium::Null,
SoF::Null,
SoD::Null,
UF::Null,
legacy::TYPE_GUILD_TROPHY_TRIBUTE_SIZE,
legacy::TYPE_GUILD_TROPHY_TRIBUTE_SIZE,
EntityLimits::npc::Null,
EntityLimits::merc::Null,
EntityLimits::bot::Null,
EntityLimits::pet::Null
},
{ // local[TypeKrono]
ClientUnknown::Null,
Client62::Null,
Titanium::Null,
SoF::Null,
SoD::Null,
UF::Null,
legacy::TYPE_KRONO_SIZE,
legacy::TYPE_KRONO_SIZE,
EntityLimits::npc::Null,
EntityLimits::merc::Null,
EntityLimits::bot::Null,
EntityLimits::pet::Null
},
{ // local[TypeOther]
ClientUnknown::Null,
Client62::Null,
Titanium::Null,
SoF::Null,
SoD::Null,
UF::Null,
legacy::TYPE_OTHER_SIZE,
legacy::TYPE_OTHER_SIZE,
EntityLimits::npc::Null,
EntityLimits::merc::Null,
EntityLimits::bot::Null,
EntityLimits::pet::Null
}
};
if ((uint16)inv_type < legacy::TypeCount)
return local[inv_type][static_cast<size_t>(versions::ValidateInventoryVersion(inventory_version))];
return NOT_USED;
return &constants_lookup_entries[static_cast<int>(versions::ValidateClientVersion(client_version))];
}
uint64 EQEmu::inventory::PossessionsBitmask(versions::InventoryVersion inventory_version)
static const EQEmu::inventory::LookupEntry inventory_lookup_entries[EQEmu::versions::InventoryVersionCount] =
{
static const uint64 local[versions::InventoryVersionCount] = {
ClientUnknown::Null,
Client62::Null,
0x000000027FDFFFFF,
0x000000027FFFFFFF,
0x000000027FFFFFFF,
0x000000027FFFFFFF,
0x00000003FFFFFFFF,
0x00000003FFFFFFFF,
EntityLimits::npc::Null,
EntityLimits::merc::Null,
EntityLimits::bot::Null,
EntityLimits::pet::Null
};
{ // Unknown
ClientUnknown::Null, ClientUnknown::Null, ClientUnknown::Null, ClientUnknown::Null, ClientUnknown::Null,
ClientUnknown::Null, ClientUnknown::Null, ClientUnknown::Null, ClientUnknown::Null, ClientUnknown::Null,
ClientUnknown::Null, ClientUnknown::Null, ClientUnknown::Null, ClientUnknown::Null, ClientUnknown::Null,
ClientUnknown::Null, ClientUnknown::Null, ClientUnknown::Null, ClientUnknown::Null, ClientUnknown::Null,
ClientUnknown::Null, ClientUnknown::Null, ClientUnknown::Null, ClientUnknown::Null, ClientUnknown::Null,
return NOT_USED;
//return local[static_cast<size_t>(versions::ValidateInventoryVersion(inventory_version))];
}
ClientUnknown::Null, ClientUnknown::Null, ClientUnknown::Null,
bool EQEmu::inventory::AllowEmptyBagInBag(versions::InventoryVersion inventory_version)
ClientUnknown::False, ClientUnknown::False, ClientUnknown::False, ClientUnknown::False
},
{ // Client62
Client62::Null, Client62::Null, Client62::Null, Client62::Null, Client62::Null,
Client62::Null, Client62::Null, Client62::Null, Client62::Null, Client62::Null,
Client62::Null, Client62::Null, Client62::Null, Client62::Null, Client62::Null,
Client62::Null, Client62::Null, Client62::Null, Client62::Null, Client62::Null,
Client62::Null, Client62::Null, Client62::Null, Client62::Null, Client62::Null,
Client62::Null, Client62::Null, Client62::Null,
Client62::False, Client62::False, Client62::False, Client62::False
},
{ // Titanium
EQEmu::legacy::TYPE_POSSESSIONS_SIZE, /*Titanium::invtype::InvTypePossessionsSize,*/ Titanium::invtype::InvTypeBankSize, Titanium::invtype::InvTypeSharedBankSize, Titanium::invtype::InvTypeTradeSize, Titanium::invtype::InvTypeWorldSize,
Titanium::invtype::InvTypeLimboSize, Titanium::invtype::InvTypeTributeSize, Titanium::Null, Titanium::Null, /*Titanium::invtype::InvTypeGuildTributeSize,*/ Titanium::invtype::InvTypeMerchantSize,
Titanium::Null, Titanium::invtype::InvTypeCorpseSize, EQEmu::legacy::TYPE_BAZAAR_SIZE, /*Titanium::invtype::InvTypeBazaarSize,*/ Titanium::invtype::InvTypeInspectSize, Titanium::Null,
Titanium::invtype::InvTypeViewMODPCSize, Titanium::invtype::InvTypeViewMODBankSize, Titanium::invtype::InvTypeViewMODSharedBankSize, Titanium::invtype::InvTypeViewMODLimboSize, Titanium::invtype::InvTypeAltStorageSize,
Titanium::invtype::InvTypeArchivedSize, Titanium::Null, Titanium::Null, Titanium::Null, Titanium::invtype::InvTypeOtherSize,
Titanium::Null, /*0x000000027FDFFFFF,*/ EQEmu::legacy::ITEM_CONTAINER_SIZE, /*Titanium::invbag::ItemBagSize,*/ EQEmu::legacy::ITEM_COMMON_SIZE, /*Titanium::invaug::ItemAugSize,*/
Titanium::inventory::AllowEmptyBagInBag, Titanium::inventory::AllowClickCastFromBag, Titanium::inventory::ConcatenateInvTypeLimbo, Titanium::inventory::AllowOverLevelEquipment
},
{ // SoF
EQEmu::legacy::TYPE_POSSESSIONS_SIZE, /*SoF::invtype::InvTypePossessionsSize,*/ SoF::invtype::InvTypeBankSize, SoF::invtype::InvTypeSharedBankSize, SoF::invtype::InvTypeTradeSize, SoF::invtype::InvTypeWorldSize,
SoF::invtype::InvTypeLimboSize, SoF::invtype::InvTypeTributeSize, SoF::Null, SoF::Null, /*SoF::invtype::InvTypeGuildTributeSize,*/ SoF::invtype::InvTypeMerchantSize,
SoF::Null, SoF::invtype::InvTypeCorpseSize, EQEmu::legacy::TYPE_BAZAAR_SIZE, /*SoF::invtype::InvTypeBazaarSize,*/ SoF::invtype::InvTypeInspectSize, SoF::Null,
SoF::invtype::InvTypeViewMODPCSize, SoF::invtype::InvTypeViewMODBankSize, SoF::invtype::InvTypeViewMODSharedBankSize, SoF::invtype::InvTypeViewMODLimboSize, SoF::invtype::InvTypeAltStorageSize,
SoF::invtype::InvTypeArchivedSize, SoF::Null, SoF::Null, SoF::Null, SoF::invtype::InvTypeOtherSize,
SoF::Null, /*0x000000027FFFFFFF,*/ EQEmu::legacy::ITEM_CONTAINER_SIZE, /*SoF::invbag::ItemBagSize,*/ EQEmu::legacy::ITEM_COMMON_SIZE, /*SoF::invaug::ItemAugSize,*/
SoF::inventory::AllowEmptyBagInBag, SoF::inventory::AllowClickCastFromBag, SoF::inventory::ConcatenateInvTypeLimbo, SoF::inventory::AllowOverLevelEquipment
},
{ // SoD
EQEmu::legacy::TYPE_POSSESSIONS_SIZE, /*SoD::invtype::InvTypePossessionsSize,*/ SoD::invtype::InvTypeBankSize, SoD::invtype::InvTypeSharedBankSize, SoD::invtype::InvTypeTradeSize, SoD::invtype::InvTypeWorldSize,
SoD::invtype::InvTypeLimboSize, SoD::invtype::InvTypeTributeSize, SoD::Null, SoD::Null, /*SoD::invtype::InvTypeGuildTributeSize,*/ SoD::invtype::InvTypeMerchantSize,
SoD::Null, SoD::invtype::InvTypeCorpseSize, EQEmu::legacy::TYPE_BAZAAR_SIZE, /*SoD::invtype::InvTypeBazaarSize,*/ SoD::invtype::InvTypeInspectSize, SoD::Null,
SoD::invtype::InvTypeViewMODPCSize, SoD::invtype::InvTypeViewMODBankSize, SoD::invtype::InvTypeViewMODSharedBankSize, SoD::invtype::InvTypeViewMODLimboSize, SoD::invtype::InvTypeAltStorageSize,
SoD::invtype::InvTypeArchivedSize, SoD::Null, SoD::Null, SoD::Null, SoD::invtype::InvTypeOtherSize,
SoD::Null, /*0x000000027FFFFFFF,*/ EQEmu::legacy::ITEM_CONTAINER_SIZE, /*SoD::invbag::ItemBagSize,*/ EQEmu::legacy::ITEM_COMMON_SIZE, /*SoD::invaug::ItemAugSize,*/
SoD::inventory::AllowEmptyBagInBag, SoD::inventory::AllowClickCastFromBag, SoD::inventory::ConcatenateInvTypeLimbo, SoD::inventory::AllowOverLevelEquipment
},
{ // UF
EQEmu::legacy::TYPE_POSSESSIONS_SIZE, /*UF::invtype::InvTypePossessionsSize,*/ UF::invtype::InvTypeBankSize, UF::invtype::InvTypeSharedBankSize, UF::invtype::InvTypeTradeSize, UF::invtype::InvTypeWorldSize,
UF::invtype::InvTypeLimboSize, UF::invtype::InvTypeTributeSize, UF::Null, UF::Null, /*UF::invtype::InvTypeGuildTributeSize,*/ UF::invtype::InvTypeMerchantSize,
UF::Null, UF::invtype::InvTypeCorpseSize, EQEmu::legacy::TYPE_BAZAAR_SIZE, /*UF::invtype::InvTypeBazaarSize,*/ UF::invtype::InvTypeInspectSize, UF::Null,
UF::invtype::InvTypeViewMODPCSize, UF::invtype::InvTypeViewMODBankSize, UF::invtype::InvTypeViewMODSharedBankSize, UF::invtype::InvTypeViewMODLimboSize, UF::invtype::InvTypeAltStorageSize,
UF::invtype::InvTypeArchivedSize, UF::Null, UF::Null, UF::Null, UF::invtype::InvTypeOtherSize,
UF::Null, /*0x000000027FFFFFFF,*/ EQEmu::legacy::ITEM_CONTAINER_SIZE, /*UF::invbag::ItemBagSize,*/ EQEmu::legacy::ITEM_COMMON_SIZE, /*UF::invaug::ItemAugSize,*/
UF::inventory::AllowEmptyBagInBag, UF::inventory::AllowClickCastFromBag, UF::inventory::ConcatenateInvTypeLimbo, UF::inventory::AllowOverLevelEquipment
},
{ // RoF
EQEmu::legacy::TYPE_POSSESSIONS_SIZE, /*RoF::invtype::InvTypePossessionsSize,*/ RoF::invtype::InvTypeBankSize, RoF::invtype::InvTypeSharedBankSize, RoF::invtype::InvTypeTradeSize, RoF::invtype::InvTypeWorldSize,
RoF::invtype::InvTypeLimboSize, RoF::invtype::InvTypeTributeSize, RoF::Null, /*RoF::invtype::InvTypeTrophyTributeSize,*/ RoF::Null, /*RoF::invtype::InvTypeGuildTributeSize,*/ RoF::invtype::InvTypeMerchantSize,
RoF::Null, /*RoF::invtype::InvTypeDeletedSize,*/ RoF::invtype::InvTypeCorpseSize, EQEmu::legacy::TYPE_BAZAAR_SIZE, /*RoF::invtype::InvTypeBazaarSize,*/ RoF::invtype::InvTypeInspectSize, RoF::Null, /*RoF::invtype::InvTypeRealEstateSize,*/
RoF::invtype::InvTypeViewMODPCSize, RoF::invtype::InvTypeViewMODBankSize, RoF::invtype::InvTypeViewMODSharedBankSize, RoF::invtype::InvTypeViewMODLimboSize, RoF::invtype::InvTypeAltStorageSize,
RoF::invtype::InvTypeArchivedSize, RoF::invtype::InvTypeMailSize, RoF::invtype::InvTypeGuildTrophyTributeSize, RoF::Null, RoF::invtype::InvTypeOtherSize,
RoF::Null, /*0x00000003FFFFFFFF,*/ EQEmu::legacy::ITEM_CONTAINER_SIZE, /*RoF::invbag::ItemBagSize,*/ EQEmu::legacy::ITEM_COMMON_SIZE, /*RoF::invaug::ItemAugSize,*/
RoF::False, /*RoF::inventory::AllowEmptyBagInBag,*/ RoF::inventory::AllowClickCastFromBag, RoF::inventory::ConcatenateInvTypeLimbo, RoF::inventory::AllowOverLevelEquipment
},
{ // RoF2
EQEmu::legacy::TYPE_POSSESSIONS_SIZE, /*RoF2::invtype::InvTypePossessionsSize,*/ RoF2::invtype::InvTypeBankSize, RoF2::invtype::InvTypeSharedBankSize, RoF2::invtype::InvTypeTradeSize, RoF2::invtype::InvTypeWorldSize,
RoF2::invtype::InvTypeLimboSize, RoF2::invtype::InvTypeTributeSize, RoF2::Null, /*RoF2::invtype::InvTypeTrophyTributeSize,*/ RoF2::Null, /*RoF2::invtype::InvTypeGuildTributeSize,*/ RoF2::invtype::InvTypeMerchantSize,
RoF2::Null, /*RoF2::invtype::InvTypeDeletedSize,*/ RoF2::invtype::InvTypeCorpseSize, EQEmu::legacy::TYPE_BAZAAR_SIZE, /*RoF2::invtype::InvTypeBazaarSize,*/ RoF2::invtype::InvTypeInspectSize, RoF2::Null, /*RoF2::invtype::InvTypeRealEstateSize*/
RoF2::invtype::InvTypeViewMODPCSize, RoF2::invtype::InvTypeViewMODBankSize, RoF2::invtype::InvTypeViewMODSharedBankSize, RoF2::invtype::InvTypeViewMODLimboSize, RoF2::invtype::InvTypeAltStorageSize,
RoF2::invtype::InvTypeArchivedSize, RoF2::invtype::InvTypeMailSize, RoF2::invtype::InvTypeGuildTrophyTributeSize, RoF2::invtype::InvTypeKronoSize, RoF2::invtype::InvTypeOtherSize,
RoF2::Null, /*0x00000003FFFFFFFF,*/ EQEmu::legacy::ITEM_CONTAINER_SIZE, /*RoF2::invbag::ItemBagSize,*/ EQEmu::legacy::ITEM_COMMON_SIZE, /*RoF2::invaug::ItemAugSize,*/
RoF2::False, /*RoF2::inventory::AllowEmptyBagInBag,*/ RoF2::inventory::AllowClickCastFromBag, RoF2::inventory::ConcatenateInvTypeLimbo, RoF2::inventory::AllowOverLevelEquipment
},
{ // NPC
EQEmu::legacy::TYPE_POSSESSIONS_SIZE, /*InvTypePossessionsSize,*/ EntityLimits::NPC::Null, EntityLimits::NPC::Null, EntityLimits::NPC::InvTypeTradeSize, EntityLimits::NPC::Null,
EntityLimits::NPC::Null, EntityLimits::NPC::Null, EntityLimits::NPC::Null, EntityLimits::NPC::Null, EntityLimits::NPC::Null,
EntityLimits::NPC::Null, EntityLimits::NPC::Null, /*InvTypeCorpseSize,*/ EntityLimits::NPC::Null, EntityLimits::NPC::Null, EntityLimits::NPC::Null,
EntityLimits::NPC::Null, EntityLimits::NPC::Null, EntityLimits::NPC::Null, EntityLimits::NPC::Null, EntityLimits::NPC::Null,
EntityLimits::NPC::Null, EntityLimits::NPC::Null, EntityLimits::NPC::Null, EntityLimits::NPC::Null, EntityLimits::NPC::Null,
EntityLimits::NPC::Null, EQEmu::legacy::ITEM_CONTAINER_SIZE, /*ItemBagSize,*/ EQEmu::legacy::ITEM_COMMON_SIZE, /*ItemAugSize,*/
EntityLimits::NPC::False, EntityLimits::NPC::False, EntityLimits::NPC::False, EntityLimits::NPC::False
},
{ // NPCMerchant
EQEmu::legacy::TYPE_POSSESSIONS_SIZE, /*InvTypePossessionsSize,*/ EntityLimits::NPCMerchant::Null, EntityLimits::NPCMerchant::Null, EntityLimits::NPCMerchant::InvTypeTradeSize, EntityLimits::NPCMerchant::Null,
EntityLimits::NPCMerchant::Null, EntityLimits::NPCMerchant::Null, EntityLimits::NPCMerchant::Null, EntityLimits::NPCMerchant::Null, EntityLimits::NPCMerchant::Null,
EntityLimits::NPCMerchant::Null, EntityLimits::NPCMerchant::Null, /*InvTypeCorpseSize,*/ EntityLimits::NPCMerchant::Null, EntityLimits::NPCMerchant::Null, EntityLimits::NPCMerchant::Null,
EntityLimits::NPCMerchant::Null, EntityLimits::NPCMerchant::Null, EntityLimits::NPCMerchant::Null, EntityLimits::NPCMerchant::Null, EntityLimits::NPCMerchant::Null,
EntityLimits::NPCMerchant::Null, EntityLimits::NPCMerchant::Null, EntityLimits::NPCMerchant::Null, EntityLimits::NPCMerchant::Null, EntityLimits::NPCMerchant::Null,
EntityLimits::NPCMerchant::Null, EQEmu::legacy::ITEM_CONTAINER_SIZE, /*ItemBagSize,*/ EQEmu::legacy::ITEM_COMMON_SIZE, /*ItemAugSize,*/
EntityLimits::NPCMerchant::False, EntityLimits::NPCMerchant::False, EntityLimits::NPCMerchant::False, EntityLimits::NPCMerchant::False
},
{ // Merc
EQEmu::legacy::TYPE_POSSESSIONS_SIZE, /*InvTypePossessionsSize,*/ EntityLimits::Merc::Null, EntityLimits::Merc::Null, EntityLimits::Merc::InvTypeTradeSize, EntityLimits::Merc::Null,
EntityLimits::Merc::Null, EntityLimits::Merc::Null, EntityLimits::Merc::Null, EntityLimits::Merc::Null, EntityLimits::Merc::Null,
EntityLimits::Merc::Null, EntityLimits::Merc::Null, /*InvTypeCorpseSize,*/ EntityLimits::Merc::Null, EntityLimits::Merc::Null, EntityLimits::Merc::Null,
EntityLimits::Merc::Null, EntityLimits::Merc::Null, EntityLimits::Merc::Null, EntityLimits::Merc::Null, EntityLimits::Merc::Null,
EntityLimits::Merc::Null, EntityLimits::Merc::Null, EntityLimits::Merc::Null, EntityLimits::Merc::Null, EntityLimits::Merc::Null,
EntityLimits::Merc::Null, EQEmu::legacy::ITEM_CONTAINER_SIZE, /*ItemBagSize,*/ EQEmu::legacy::ITEM_COMMON_SIZE, /*ItemAugSize,*/
EntityLimits::Merc::False, EntityLimits::Merc::False, EntityLimits::Merc::False, EntityLimits::Merc::False
},
{ // Bot
EQEmu::legacy::TYPE_POSSESSIONS_SIZE, /*InvTypePossessionsSize,*/ EntityLimits::Bot::Null, EntityLimits::Bot::Null, EntityLimits::Bot::InvTypeTradeSize, EntityLimits::Bot::Null,
EntityLimits::Bot::Null, EntityLimits::Bot::Null, EntityLimits::Bot::Null, EntityLimits::Bot::Null, EntityLimits::Bot::Null,
EntityLimits::Bot::Null, EntityLimits::Bot::Null, /*InvTypeCorpseSize,*/ EntityLimits::Bot::Null, EntityLimits::Bot::Null, EntityLimits::Bot::Null,
EntityLimits::Bot::Null, EntityLimits::Bot::Null, EntityLimits::Bot::Null, EntityLimits::Bot::Null, EntityLimits::Bot::Null,
EntityLimits::Bot::Null, EntityLimits::Bot::Null, EntityLimits::Bot::Null, EntityLimits::Bot::Null, EntityLimits::Bot::Null,
EntityLimits::Bot::Null, EQEmu::legacy::ITEM_CONTAINER_SIZE, /*ItemBagSize,*/ EQEmu::legacy::ITEM_COMMON_SIZE, /*ItemAugSize,*/
EntityLimits::Bot::False, EntityLimits::Bot::False, EntityLimits::Bot::False, EntityLimits::Bot::False
},
{ // ClientPet
EQEmu::legacy::TYPE_POSSESSIONS_SIZE, /*InvTypePossessionsSize,*/ EntityLimits::ClientPet::Null, EntityLimits::ClientPet::Null, EntityLimits::ClientPet::InvTypeTradeSize, EntityLimits::ClientPet::Null,
EntityLimits::ClientPet::Null, EntityLimits::ClientPet::Null, EntityLimits::ClientPet::Null, EntityLimits::ClientPet::Null, EntityLimits::ClientPet::Null,
EntityLimits::ClientPet::Null, EntityLimits::ClientPet::Null, /*InvTypeCorpseSize,*/ EntityLimits::ClientPet::Null, EntityLimits::ClientPet::Null, EntityLimits::ClientPet::Null,
EntityLimits::ClientPet::Null, EntityLimits::ClientPet::Null, EntityLimits::ClientPet::Null, EntityLimits::ClientPet::Null, EntityLimits::ClientPet::Null,
EntityLimits::ClientPet::Null, EntityLimits::ClientPet::Null, EntityLimits::ClientPet::Null, EntityLimits::ClientPet::Null, EntityLimits::ClientPet::Null,
EntityLimits::ClientPet::Null, EQEmu::legacy::ITEM_CONTAINER_SIZE, /*ItemBagSize,*/ EQEmu::legacy::ITEM_COMMON_SIZE, /*ItemAugSize,*/
EntityLimits::ClientPet::False, EntityLimits::ClientPet::False, EntityLimits::ClientPet::False, EntityLimits::ClientPet::False
},
{ // NPCPet
EQEmu::legacy::TYPE_POSSESSIONS_SIZE, /*InvTypePossessionsSize,*/ EntityLimits::NPCPet::Null, EntityLimits::NPCPet::Null, EntityLimits::NPCPet::InvTypeTradeSize, EntityLimits::NPCPet::Null,
EntityLimits::NPCPet::Null, EntityLimits::NPCPet::Null, EntityLimits::NPCPet::Null, EntityLimits::NPCPet::Null, EntityLimits::NPCPet::Null,
EntityLimits::NPCPet::Null, EntityLimits::NPCPet::Null, /*InvTypeCorpseSize,*/ EntityLimits::NPCPet::Null, EntityLimits::NPCPet::Null, EntityLimits::NPCPet::Null,
EntityLimits::NPCPet::Null, EntityLimits::NPCPet::Null, EntityLimits::NPCPet::Null, EntityLimits::NPCPet::Null, EntityLimits::NPCPet::Null,
EntityLimits::NPCPet::Null, EntityLimits::NPCPet::Null, EntityLimits::NPCPet::Null, EntityLimits::NPCPet::Null, EntityLimits::NPCPet::Null,
EntityLimits::NPCPet::Null, EQEmu::legacy::ITEM_CONTAINER_SIZE, /*ItemBagSize,*/ EQEmu::legacy::ITEM_COMMON_SIZE, /*ItemAugSize,*/
EntityLimits::NPCPet::False, EntityLimits::NPCPet::False, EntityLimits::NPCPet::False, EntityLimits::NPCPet::False
},
{ // MercPet
EQEmu::legacy::TYPE_POSSESSIONS_SIZE, /*InvTypePossessionsSize,*/ EntityLimits::MercPet::Null, EntityLimits::MercPet::Null, EntityLimits::MercPet::InvTypeTradeSize, EntityLimits::MercPet::Null,
EntityLimits::MercPet::Null, EntityLimits::MercPet::Null, EntityLimits::MercPet::Null, EntityLimits::MercPet::Null, EntityLimits::MercPet::Null,
EntityLimits::MercPet::Null, EntityLimits::MercPet::Null, /*InvTypeCorpseSize,*/ EntityLimits::MercPet::Null, EntityLimits::MercPet::Null, EntityLimits::MercPet::Null,
EntityLimits::MercPet::Null, EntityLimits::MercPet::Null, EntityLimits::MercPet::Null, EntityLimits::MercPet::Null, EntityLimits::MercPet::Null,
EntityLimits::MercPet::Null, EntityLimits::MercPet::Null, EntityLimits::MercPet::Null, EntityLimits::MercPet::Null, EntityLimits::MercPet::Null,
EntityLimits::MercPet::Null, EQEmu::legacy::ITEM_CONTAINER_SIZE, /*ItemBagSize,*/ EQEmu::legacy::ITEM_COMMON_SIZE, /*ItemAugSize,*/
EntityLimits::MercPet::False, EntityLimits::MercPet::False, EntityLimits::MercPet::False, EntityLimits::MercPet::False
},
{ // BotPet
EQEmu::legacy::TYPE_POSSESSIONS_SIZE, /*InvTypePossessionsSize,*/ EntityLimits::BotPet::Null, EntityLimits::BotPet::Null, EntityLimits::BotPet::InvTypeTradeSize, EntityLimits::BotPet::Null,
EntityLimits::BotPet::Null, EntityLimits::BotPet::Null, EntityLimits::BotPet::Null, EntityLimits::BotPet::Null, EntityLimits::BotPet::Null,
EntityLimits::BotPet::Null, EntityLimits::BotPet::Null, /*InvTypeCorpseSize,*/ EntityLimits::BotPet::Null, EntityLimits::BotPet::Null, EntityLimits::BotPet::Null,
EntityLimits::BotPet::Null, EntityLimits::BotPet::Null, EntityLimits::BotPet::Null, EntityLimits::BotPet::Null, EntityLimits::BotPet::Null,
EntityLimits::BotPet::Null, EntityLimits::BotPet::Null, EntityLimits::BotPet::Null, EntityLimits::BotPet::Null, EntityLimits::BotPet::Null,
EntityLimits::BotPet::Null, EQEmu::legacy::ITEM_CONTAINER_SIZE, /*ItemBagSize,*/ EQEmu::legacy::ITEM_COMMON_SIZE, /*ItemAugSize,*/
EntityLimits::BotPet::False, EntityLimits::BotPet::False, EntityLimits::BotPet::False, EntityLimits::BotPet::False
},
{ // OfflineTitanium
Titanium::Null, Titanium::Null, Titanium::Null, Titanium::invtype::InvTypeTradeSize, Titanium::Null,
Titanium::Null, Titanium::Null, Titanium::Null, Titanium::Null, Titanium::invtype::InvTypeMerchantSize,
Titanium::Null, Titanium::Null, Titanium::Null, /*Titanium::invtype::InvTypeBazaarSize,*/ Titanium::invtype::InvTypeInspectSize, Titanium::Null,
Titanium::invtype::InvTypeViewMODPCSize, Titanium::invtype::InvTypeViewMODBankSize, Titanium::invtype::InvTypeViewMODSharedBankSize, Titanium::invtype::InvTypeViewMODLimboSize, Titanium::Null,
Titanium::Null, Titanium::Null, Titanium::Null, Titanium::Null, Titanium::Null,
Titanium::Null, EQEmu::legacy::ITEM_CONTAINER_SIZE, /*Titanium::Null,*/ Titanium::Null,
Titanium::False, Titanium::False, Titanium::False, Titanium::False
},
{ // OfflineSoF
SoF::Null, SoF::Null, SoF::Null, SoF::invtype::InvTypeTradeSize, SoF::Null,
SoF::Null, SoF::Null, SoF::Null, SoF::Null, SoF::invtype::InvTypeMerchantSize,
SoF::Null, SoF::Null, SoF::Null, /*SoF::invtype::InvTypeBazaarSize,*/ SoF::invtype::InvTypeInspectSize, SoF::Null,
SoF::invtype::InvTypeViewMODPCSize, SoF::invtype::InvTypeViewMODBankSize, SoF::invtype::InvTypeViewMODSharedBankSize, SoF::invtype::InvTypeViewMODLimboSize, SoF::Null,
SoF::Null, SoF::Null, SoF::Null, SoF::Null, SoF::Null,
SoF::Null, EQEmu::legacy::ITEM_CONTAINER_SIZE, /*SoF::Null,*/ SoF::Null,
SoF::False, SoF::False, SoF::False, SoF::False
},
{ // OfflineSoD
SoD::Null, SoD::Null, SoD::Null, SoD::invtype::InvTypeTradeSize, SoD::Null,
SoD::Null, SoD::Null, SoD::Null, SoD::Null, SoD::invtype::InvTypeMerchantSize,
SoD::Null, SoD::Null, SoD::Null, /*SoD::invtype::InvTypeBazaarSize,*/ SoD::invtype::InvTypeInspectSize, SoD::Null,
SoD::invtype::InvTypeViewMODPCSize, SoD::invtype::InvTypeViewMODBankSize, SoD::invtype::InvTypeViewMODSharedBankSize, SoD::invtype::InvTypeViewMODLimboSize, SoD::Null,
SoD::Null, SoD::Null, SoD::Null, SoD::Null, SoD::Null,
SoD::Null, EQEmu::legacy::ITEM_CONTAINER_SIZE, /*SoD::Null,*/ SoD::Null,
SoD::False, SoD::False, SoD::False, SoD::False
},
{ // OfflineUF
UF::Null, UF::Null, UF::Null, UF::invtype::InvTypeTradeSize, UF::Null,
UF::Null, UF::Null, UF::Null, UF::Null, UF::invtype::InvTypeMerchantSize,
UF::Null, UF::Null, UF::Null, /*UF::invtype::InvTypeBazaarSize,*/ UF::invtype::InvTypeInspectSize, UF::Null,
UF::invtype::InvTypeViewMODPCSize, UF::invtype::InvTypeViewMODBankSize, UF::invtype::InvTypeViewMODSharedBankSize, UF::invtype::InvTypeViewMODLimboSize, UF::Null,
UF::Null, UF::Null, UF::Null, UF::Null, UF::Null,
UF::Null, EQEmu::legacy::ITEM_CONTAINER_SIZE, /*UF::Null,*/ UF::Null,
UF::False, UF::False, UF::False, UF::False
},
{ // OfflineRoF
RoF::Null, RoF::Null, RoF::Null, RoF::invtype::InvTypeTradeSize, RoF::Null,
RoF::Null, RoF::Null, RoF::Null, RoF::Null, RoF::invtype::InvTypeMerchantSize,
RoF::Null, RoF::Null, RoF::Null, /*RoF::invtype::InvTypeBazaarSize,*/ RoF::invtype::InvTypeInspectSize, RoF::Null,
RoF::invtype::InvTypeViewMODPCSize, RoF::invtype::InvTypeViewMODBankSize, RoF::invtype::InvTypeViewMODSharedBankSize, RoF::invtype::InvTypeViewMODLimboSize, RoF::Null,
RoF::Null, RoF::Null, RoF::Null, RoF::Null, RoF::Null,
RoF::Null, EQEmu::legacy::ITEM_CONTAINER_SIZE, /*RoF::Null,*/ RoF::Null,
RoF::False, RoF::False, RoF::False, RoF::False
},
{ // OfflineRoF2
RoF2::Null, RoF2::Null, RoF2::Null, RoF2::invtype::InvTypeTradeSize, RoF2::Null,
RoF2::Null, RoF2::Null, RoF2::Null, RoF2::Null, RoF2::invtype::InvTypeMerchantSize,
RoF2::Null, RoF2::Null, RoF2::Null, /*RoF2::invtype::InvTypeBazaarSize,*/ RoF2::invtype::InvTypeInspectSize, RoF2::Null,
RoF2::invtype::InvTypeViewMODPCSize, RoF2::invtype::InvTypeViewMODBankSize, RoF2::invtype::InvTypeViewMODSharedBankSize, RoF2::invtype::InvTypeViewMODLimboSize, RoF2::Null,
RoF2::Null, RoF2::Null, RoF2::Null, RoF2::Null, RoF2::Null,
RoF2::Null, EQEmu::legacy::ITEM_CONTAINER_SIZE, /*RoF2::Null,*/ RoF2::Null,
RoF2::False, RoF2::False, RoF2::False, RoF2::False
}
};
const EQEmu::inventory::LookupEntry* EQEmu::inventory::Lookup(versions::InventoryVersion inventory_version)
{
static const bool local[versions::InventoryVersionCount] = {
ClientUnknown::False,
Client62::False,
Titanium::behavior::AllowEmptyBagInBag,
SoF::behavior::AllowEmptyBagInBag,
SoD::behavior::AllowEmptyBagInBag,
UF::behavior::AllowEmptyBagInBag,
RoF::behavior::AllowEmptyBagInBag,
RoF2::behavior::AllowEmptyBagInBag,
EntityLimits::npc::False,
EntityLimits::merc::False,
EntityLimits::bot::False,
EntityLimits::pet::False
};
return false;
//return local[static_cast<size_t>(versions::ValidateInventoryVersion(inventory_version))];
return &inventory_lookup_entries[static_cast<int>(versions::ValidateInventoryVersion(inventory_version))];
}
bool EQEmu::inventory::AllowClickCastFromBag(versions::InventoryVersion inventory_version)
static const EQEmu::behavior::LookupEntry behavior_lookup_entries[EQEmu::versions::InventoryVersionCount] =
{
static const bool local[versions::InventoryVersionCount] = {
ClientUnknown::False,
Client62::False,
Titanium::behavior::AllowClickCastFromBag,
SoF::behavior::AllowClickCastFromBag,
SoD::behavior::AllowClickCastFromBag,
UF::behavior::AllowClickCastFromBag,
RoF::behavior::AllowClickCastFromBag,
RoF2::behavior::AllowClickCastFromBag,
EntityLimits::npc::False,
EntityLimits::merc::False,
EntityLimits::bot::False,
EntityLimits::pet::False
};
{ // Unknown
ClientUnknown::True
},
{ // Client62
Client62::True
},
{ // Titanium
Titanium::behavior::CoinHasWeight
},
{ // SoF
SoF::behavior::CoinHasWeight
},
{ // SoD
SoD::behavior::CoinHasWeight
},
{ // UF
UF::behavior::CoinHasWeight
},
{ // RoF
RoF::behavior::CoinHasWeight
},
{ // RoF2
RoF2::behavior::CoinHasWeight
},
{ // NPC
EntityLimits::NPC::True /*CoinHasWeight*/
},
{ // NPCMerchant
EntityLimits::NPC::True /*CoinHasWeight*/
},
{ // Merc
EntityLimits::Merc::True /*CoinHasWeight*/
},
{ // Bot
EntityLimits::Bot::True /*CoinHasWeight*/
},
{ // ClientPet
EntityLimits::ClientPet::True /*CoinHasWeight*/
},
{ // NPCPet
EntityLimits::NPCPet::True /*CoinHasWeight*/
},
{ // MercPet
EntityLimits::MercPet::True /*CoinHasWeight*/
},
{ // BotPet
EntityLimits::BotPet::True /*CoinHasWeight*/
},
{ // OfflineTitanium
Titanium::False
},
{ // OfflineSoF
SoF::False
},
{ // OfflineSoD
SoD::False
},
{ // OfflineUF
UF::False
},
{ // OfflineRoF
RoF::False
},
{ // OfflineRoF2
RoF2::False
}
};
return local[static_cast<size_t>(versions::ValidateInventoryVersion(inventory_version))];
}
uint16 EQEmu::inventory::ItemAugSize(versions::InventoryVersion inventory_version)
const EQEmu::behavior::LookupEntry* EQEmu::behavior::Lookup(versions::InventoryVersion inventory_version)
{
static const uint16 local[versions::InventoryVersionCount] = {
ClientUnknown::Null,
Client62::Null,
legacy::ITEM_COMMON_SIZE,
legacy::ITEM_COMMON_SIZE,
legacy::ITEM_COMMON_SIZE,
legacy::ITEM_COMMON_SIZE,
legacy::ITEM_COMMON_SIZE,
legacy::ITEM_COMMON_SIZE,
legacy::ITEM_COMMON_SIZE,
legacy::ITEM_COMMON_SIZE,
legacy::ITEM_COMMON_SIZE,
legacy::ITEM_COMMON_SIZE
};
return local[static_cast<size_t>(versions::ValidateInventoryVersion(inventory_version))];
}
uint16 EQEmu::inventory::ItemBagSize(versions::InventoryVersion inventory_version)
{
static const uint16 local[versions::InventoryVersionCount] = {
ClientUnknown::Null,
Client62::Null,
legacy::ITEM_CONTAINER_SIZE,
legacy::ITEM_CONTAINER_SIZE,
legacy::ITEM_CONTAINER_SIZE,
legacy::ITEM_CONTAINER_SIZE,
legacy::ITEM_CONTAINER_SIZE,
legacy::ITEM_CONTAINER_SIZE,
legacy::ITEM_CONTAINER_SIZE,
legacy::ITEM_CONTAINER_SIZE,
legacy::ITEM_CONTAINER_SIZE,
legacy::ITEM_CONTAINER_SIZE
};
return local[static_cast<size_t>(versions::ValidateInventoryVersion(inventory_version))];
}
bool EQEmu::profile::CoinHasWeight(versions::InventoryVersion inventory_version)
{
static const bool local[versions::InventoryVersionCount] = {
ClientUnknown::True,
Client62::True,
Titanium::behavior::CoinHasWeight,
SoF::behavior::CoinHasWeight,
SoD::behavior::CoinHasWeight,
UF::behavior::CoinHasWeight,
RoF::behavior::CoinHasWeight,
RoF::behavior::CoinHasWeight,
EntityLimits::npc::True,
EntityLimits::merc::True,
EntityLimits::bot::True,
EntityLimits::pet::True
};
return local[static_cast<size_t>(versions::ValidateInventoryVersion(inventory_version))];
return &behavior_lookup_entries[static_cast<int>(versions::ValidateInventoryVersion(inventory_version))];
}
+30 -16
View File
@@ -1,4 +1,4 @@
/* EQEMu: Everquest Server Emulator
/* EQEMu: Everquest Server Emulator
Copyright (C) 2001-2016 EQEMu Development Team (http://eqemulator.net)
@@ -10,7 +10,7 @@
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.
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
@@ -20,9 +20,10 @@
#ifndef COMMON_EQ_LIMITS_H
#define COMMON_EQ_LIMITS_H
#include "emu_legacy.h"
#include "types.h"
#include "eq_constants.h"
#include "inventory_version.h"
#include "emu_versions.h"
#include "../common/patches/titanium_limits.h"
#include "../common/patches/sof_limits.h"
#include "../common/patches/sod_limits.h"
@@ -34,30 +35,43 @@
namespace EQEmu
{
namespace constants {
extern size_t CharacterCreationLimit(versions::ClientVersion client_version);
class LookupEntry {
public:
size_t CharacterCreationLimit;
};
const LookupEntry* Lookup(versions::ClientVersion client_version);
} /*constants*/
namespace inventory {
extern uint16 InventoryTypeSize(versions::InventoryVersion inventory_version, int16 inv_type);
extern uint64 PossessionsBitmask(versions::InventoryVersion inventory_version);
class LookupEntry {
public:
size_t InventoryTypeSize[legacy::TypeCount];
extern bool AllowEmptyBagInBag(versions::InventoryVersion inventory_version);
extern bool AllowClickCastFromBag(versions::InventoryVersion inventory_version);
uint64 PossessionsBitmask;
size_t ItemBagSize;
size_t ItemAugSize;
extern uint16 ItemAugSize(versions::InventoryVersion inventory_version);
extern uint16 ItemBagSize(versions::InventoryVersion inventory_version);
bool AllowEmptyBagInBag;
bool AllowClickCastFromBag;
bool ConcatenateInvTypeLimbo;
bool AllowOverLevelEquipment;
};
extern bool ConcatenateInvTypeLimbo(versions::InventoryVersion inventory_version);
extern bool AllowOverLevelEquipment(versions::InventoryVersion inventory_version);
const LookupEntry* Lookup(versions::InventoryVersion inventory_version);
} /*inventory*/
namespace profile {
extern bool CoinHasWeight(versions::InventoryVersion inventory_version);
namespace behavior {
class LookupEntry {
public:
bool CoinHasWeight;
};
} /*profile*/
const LookupEntry* Lookup(versions::InventoryVersion inventory_version);
} /*behavior*/
} /*EQEmu*/
+73 -140
View File
@@ -25,15 +25,17 @@
#include <list>
#include <time.h>
#include "../common/version.h"
//#include "../common/item_struct.h"
#include "emu_constants.h"
#include "textures.h"
static const uint32 BUFF_COUNT = 25;
static const uint32 PET_BUFF_COUNT = 30;
static const uint32 MAX_MERC = 100;
static const uint32 MAX_MERC_GRADES = 10;
static const uint32 MAX_MERC_STANCES = 10;
static const uint32 BLOCKED_BUFF_COUNT = 20;
#include "emu_constants.h"
/*
** Compiler override to ensure
@@ -125,37 +127,7 @@ struct LDoNTrapTemplate
// All clients translate the character select information to some degree
struct Color_Struct
{
union {
struct {
uint8 Blue;
uint8 Green;
uint8 Red;
uint8 UseTint; // if there's a tint this is FF
} RGB;
uint32 Color;
};
};
struct EquipStruct
{
uint32 Material;
uint32 Unknown1;
uint32 EliteMaterial;
uint32 HeroForgeModel;
uint32 Material2; // Same as material?
};
struct CharSelectEquip
{
uint32 Material;
uint32 Unknown1;
uint32 EliteMaterial;
uint32 HeroForgeModel;
uint32 Material2;
Color_Struct Color;
};
struct CharSelectEquip : EQEmu::Texture_Struct, EQEmu::Tint_Struct {};
// RoF2-based hybrid struct
struct CharacterSelectEntry_Struct
@@ -170,7 +142,7 @@ struct CharacterSelectEntry_Struct
uint16 Instance;
uint8 Gender;
uint8 Face;
CharSelectEquip Equip[9];
CharSelectEquip Equip[EQEmu::textures::TextureCount];
uint8 Unknown15; // Seen FF
uint8 Unknown19; // Seen FF
uint32 DrakkinTattoo;
@@ -279,22 +251,7 @@ struct Spawn_Struct {
/*0189*/ uint32 petOwnerId; // If this is a pet, the spawn id of owner
/*0193*/ uint8 guildrank; // 0=normal, 1=officer, 2=leader
/*0194*/ uint8 unknown0194[3];
/*0197*/ union
{
struct
{
/*0000*/ EquipStruct equip_helmet; // Equipment: Helmet visual
/*0000*/ EquipStruct equip_chest; // Equipment: Chest visual
/*0000*/ EquipStruct equip_arms; // Equipment: Arms visual
/*0000*/ EquipStruct equip_bracers; // Equipment: Wrist visual
/*0000*/ EquipStruct equip_hands; // Equipment: Hands visual
/*0000*/ EquipStruct equip_legs; // Equipment: Legs visual
/*0000*/ EquipStruct equip_feet; // Equipment: Boots visual
/*0000*/ EquipStruct equip_primary; // Equipment: Main visual
/*0000*/ EquipStruct equip_secondary; // Equipment: Off visual
} equip;
/*0000*/ EquipStruct equipment[EQEmu::legacy::MaterialCount];
};
/*0197*/ EQEmu::TextureProfile equipment;
/*0233*/ float runspeed; // Speed when running
/*0036*/ uint8 afk; // 0=no, 1=afk
/*0238*/ uint32 guildID; // Current guild
@@ -325,22 +282,7 @@ union
/*0340*/ uint32 spawnId; // Spawn Id
/*0344*/ uint8 unknown0344[3];
/*0347*/ uint8 IsMercenary;
/*0348*/ union
{
struct
{
/*0348*/ Color_Struct color_helmet; // Color of helmet item
/*0352*/ Color_Struct color_chest; // Color of chest item
/*0356*/ Color_Struct color_arms; // Color of arms item
/*0360*/ Color_Struct color_bracers; // Color of bracers item
/*0364*/ Color_Struct color_hands; // Color of hands item
/*0368*/ Color_Struct color_legs; // Color of legs item
/*0372*/ Color_Struct color_feet; // Color of feet item
/*0376*/ Color_Struct color_primary; // Color of primary item
/*0380*/ Color_Struct color_secondary; // Color of secondary item
} equipment_colors;
/*0348*/ Color_Struct colors[EQEmu::legacy::MaterialCount]; // Array elements correspond to struct equipment_colors above
};
/*0348*/ EQEmu::TintProfile equipment_tint;
/*0384*/ uint8 lfg; // 0=off, 1=lfg on
/*0385*/
@@ -445,7 +387,19 @@ struct MemorizeSpell_Struct {
uint32 slot; // Spot in the spell book/memorized slot
uint32 spell_id; // Spell id (200 or c8 is minor healing, etc)
uint32 scribing; // 1 if memorizing a spell, set to 0 if scribing to book, 2 if un-memming
uint32 unknown12;
uint32 reduction; // lower reuse
};
/*
** Linked Spell Reuse Timer
** Length: 12
** Comes before the OP_Memorize
** Live (maybe TDS steam) has an extra DWORD after timer_id
*/
struct LinkedSpellReuseTimer_Struct {
uint32 timer_id; // Timer ID of the spell
uint32 end_time; // timestamp of when it will be ready
uint32 start_time; // timestamp of when it started
};
/*
@@ -478,10 +432,11 @@ struct DeleteSpell_Struct
struct ManaChange_Struct
{
uint32 new_mana; // New Mana AMount
uint32 stamina;
uint32 spell_id;
uint32 unknown12;
/*00*/ uint32 new_mana; // New Mana AMount
/*04*/ uint32 stamina;
/*08*/ uint32 spell_id;
/*12*/ uint8 keepcasting; // won't stop the cast. Change mana while casting?
/*13*/ uint8 padding[3]; // client doesn't read it, garbage data seems like
};
struct SwapSpell_Struct
@@ -547,30 +502,28 @@ struct SpawnAppearance_Struct
// this is used inside profile
struct SpellBuff_Struct
{
/*000*/ uint8 slotid; //badly named... seems to be 2 for a real buff, 0 otherwise
/*001*/ uint8 level;
/*000*/ uint8 effect_type; // 0 = no buff, 2 = buff, 4 = inverse affects of buff
/*001*/ uint8 level;
/*002*/ uint8 bard_modifier;
/*003*/ uint8 effect; //not real
/*003*/ uint8 unknown003; // MQ2 used to call this "damage shield" -- don't see client referencing it, so maybe server side DS type tracking? -- OSX client calls this "activated"
/*004*/ uint32 spellid;
/*008*/ int32 duration;
/*012*/ uint32 counters;
/*016*/ uint32 player_id; //'global' ID of the caster, for wearoff messages
/*020*/
/*008*/ int32 duration;
/*012*/ uint32 counters; // single book keeping value (counters, rune/vie)
/*016*/ uint32 player_id; // caster ID, pretty sure just zone ID
// extra stuff for newer packets
/*020*/ uint32 num_hits;
/*024*/ float y; // referenced by SPA 441
/*028*/ float x; // unsure if all buffs get them
/*032*/ float z; // as valid data
/*036*/
};
struct SpellBuffFade_Struct {
struct SpellBuffPacket_Struct {
/*000*/ uint32 entityid;
/*004*/ uint8 slot;
/*005*/ uint8 level;
/*006*/ uint8 effect;
/*007*/ uint8 unknown7;
/*008*/ uint32 spellid;
/*012*/ int32 duration;
/*016*/ uint32 num_hits;
/*020*/ uint32 unknown020; //prolly global player ID
/*024*/ uint32 slotid;
/*028*/ uint32 bufffade;
/*032*/
/*004*/ SpellBuff_Struct buff;
/*040*/ uint32 slotid;
/*044*/ uint32 bufffade;
/*048*/
};
// Underfoot & later struct.
@@ -583,8 +536,8 @@ struct BuffRemoveRequest_Struct
struct PetBuff_Struct {
/*000*/ uint32 petid;
/*004*/ uint32 spellid[BUFF_COUNT+5];
/*124*/ int32 ticsremaining[BUFF_COUNT+5];
/*004*/ uint32 spellid[PET_BUFF_COUNT];
/*124*/ int32 ticsremaining[PET_BUFF_COUNT];
/*244*/ uint32 buffcount;
};
@@ -881,7 +834,7 @@ struct SuspendedMinion_Struct
/*002*/ uint32 HP;
/*006*/ uint32 Mana;
/*010*/ SpellBuff_Struct Buffs[BUFF_COUNT];
/*510*/ uint32 Items[EQEmu::legacy::MaterialCount];
/*510*/ EQEmu::TextureShortProfile Items;
/*546*/ char Name[64];
/*610*/
};
@@ -895,7 +848,7 @@ struct SuspendedMinion_Struct
*/
static const uint32 MAX_PP_LANGUAGE = 28;
static const uint32 MAX_PP_SPELLBOOK = 480; // Set for all functions
static const uint32 MAX_PP_MEMSPELL = 9; // Set to latest client so functions can work right
static const uint32 MAX_PP_MEMSPELL = static_cast<uint32>(EQEmu::CastingSlot::MaxGems); // Set to latest client so functions can work right -- 12
static const uint32 MAX_PP_REF_SPELLBOOK = 480; // Set for Player Profile size retain
static const uint32 MAX_PP_REF_MEMSPELL = 9; // Set for Player Profile size retain
@@ -976,7 +929,7 @@ struct PlayerProfile_Struct
/*0245*/ uint8 guildbanker;
/*0246*/ uint8 unknown0246[6]; //
/*0252*/ uint32 intoxication;
/*0256*/ uint32 spellSlotRefresh[MAX_PP_REF_MEMSPELL]; //in ms
/*0256*/ uint32 spellSlotRefresh[MAX_PP_MEMSPELL]; //in ms
/*0292*/ uint32 abilitySlotRefresh;
/*0296*/ uint8 haircolor; // Player hair color
/*0297*/ uint8 beardcolor; // Player beard color
@@ -989,9 +942,9 @@ struct PlayerProfile_Struct
/*0304*/ uint8 ability_time_minutes;
/*0305*/ uint8 ability_time_hours; //place holder
/*0306*/ uint8 unknown0306[6]; // @bp Spacer/Flag?
/*0312*/ uint32 item_material[EQEmu::legacy::MaterialCount]; // Item texture/material of worn/held items
/*0312*/ EQEmu::TextureShortProfile item_material; // Item texture/material of worn/held items
/*0348*/ uint8 unknown0348[44];
/*0392*/ Color_Struct item_tint[EQEmu::legacy::MaterialCount];
/*0392*/ EQEmu::TintProfile item_tint;
/*0428*/ AA_Array aa_array[MAX_PP_AA_ARRAY];
/*2348*/ float unknown2384; //seen ~128, ~47
/*2352*/ char servername[32]; // length probably not right
@@ -1017,7 +970,7 @@ struct PlayerProfile_Struct
/*2580*/ uint8 unknown2616[4];
/*2584*/ uint32 spell_book[MAX_PP_REF_SPELLBOOK];
/*4504*/ uint8 unknown4540[128]; // Was [428] all 0xff
/*4632*/ uint32 mem_spells[MAX_PP_REF_MEMSPELL];
/*4632*/ uint32 mem_spells[MAX_PP_MEMSPELL];
/*4668*/ uint8 unknown4704[32]; //
/*4700*/ float y; // Player y position
/*4704*/ float x; // Player x position
@@ -1226,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*/ Color_Struct color;
/*022*/ EQEmu::Tint_Struct color;
/*026*/ uint8 wear_slot_id;
/*027*/
};
@@ -1522,7 +1475,7 @@ enum ItemPacketType
ItemPacketLoot = 0x66,
ItemPacketTrade = 0x67,
ItemPacketCharInventory = 0x69,
ItemPacketSummonItem = 0x6A,
ItemPacketLimbo = 0x6A,
ItemPacketWorldContainer = 0x6B,
ItemPacketTributeItem = 0x6C,
ItemPacketGuildTribute = 0x6D,
@@ -1536,15 +1489,15 @@ enum ItemPacketType
// ItemPacketTradeView = /*101*/ 0x65,
// ItemPacketLoot = /*102*/ 0x66,
// ItemPacketTrade = /*103*/ 0x67,
// ItemPacketCharInventory = /*105*/ 0x69,
// ItemPacketLimbo = /*106*/ 0x6A, // name change
// ItemPacketCharInventory = /*105*/ 0x69, // 105 looks like raw item packet (no appearance update) thru shared bank..110, possibly possessions with appearance update
// ItemPacketLimbo = /*106*/ 0x6A,
// ItemPacketWorldContainer = /*107*/ 0x6B,
// ItemPacketTributeItem = /*108*/ 0x6C,
// ItemPacketGuildTribute = /*109*/ 0x6D, // missing from EQEmu
// ItemPacket10 = /*110*/ 0x6E,
// ItemPacket11 = /*111*/ 0x6F, // UF+ (equipment slots only) (RoF+ checks '(WORD*)slot + 4 != -1' [(WORD*)]slot + 2 would be bag index - if used) (guess)
// ItemPacket11 = /*111*/ 0x6F, // UF+ (equipment slots only) (RoF+ checks '(WORD*)slot + 4 != -1' [(WORD*)]slot + 2 would be bag index - if used) (guess) (appearance (over-level) items?)
// ItemPacket12 = /*112*/ 0x70, // RoF+ (causes stat update) (could be TrophyTribute and GuildTrophyTribute together - two case methodology - is it checking for GuildID?)
// ItemPacketRecovery = /*113*/ 0x71, (same handler as merchant..exception: parameter is '1' versus merchant '0' looks like tab id)
// ItemPacketMerchantRecovery = /*113*/ 0x71,
// ItemPacket14 = /*115*/ 0x73, (real estate/moving crate?)
// ItemPacket__ = /*xxx*/ 0xXX // switch 'default' - all clients
//};
@@ -1981,8 +1934,7 @@ struct Merchant_Sell_Struct {
/*004*/ uint32 playerid; // Player's entity id
/*008*/ uint32 itemslot;
uint32 unknown12;
/*016*/ uint8 quantity; // Already sold
/*017*/ uint8 Unknown016[3];
/*016*/ uint32 quantity;
/*020*/ uint32 price;
};
struct Merchant_Purchase_Struct {
@@ -2119,7 +2071,7 @@ struct AdventureLeaderboard_Struct
/*struct Item_Shop_Struct {
uint16 merchantid;
uint8 itemtype;
EQEmu::Item_Struct item;
EQEmu::ItemBase item;
uint8 iss_unknown001[6];
};*/
@@ -2145,7 +2097,7 @@ struct Illusion_Struct { //size: 256 - SoF
/*092*/ uint32 drakkin_heritage; //
/*096*/ uint32 drakkin_tattoo; //
/*100*/ uint32 drakkin_details; //
/*104*/ uint32 armor_tint[EQEmu::legacy::MaterialCount]; //
/*104*/ EQEmu::TintProfile armor_tint; //
/*140*/ uint8 eyecolor1; // Field Not Identified in any Illusion Struct
/*141*/ uint8 eyecolor2; // Field Not Identified in any Illusion Struct
/*142*/ uint8 unknown138[114]; //
@@ -2556,23 +2508,25 @@ struct BookRequest_Struct {
*/
struct Object_Struct {
/*00*/ uint32 linked_list_addr[2];// They are, get this, prev and next, ala linked list
/*08*/ uint16 size; //
/*08*/ float 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 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*/
/*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
};
// 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
@@ -3415,27 +3369,6 @@ struct PetitionBug_Struct{
char text[1028];
};
struct DyeStruct
{
union
{
struct
{
struct Color_Struct head;
struct Color_Struct chest;
struct Color_Struct arms;
struct Color_Struct wrists;
struct Color_Struct hands;
struct Color_Struct legs;
struct Color_Struct feet;
struct Color_Struct primary; // you can't actually dye this
struct Color_Struct secondary; // or this
}
dyes;
struct Color_Struct dye[EQEmu::legacy::MaterialCount];
};
};
struct ApproveZone_Struct {
char name[64];
uint32 zoneid;
+1 -1
View File
@@ -4,7 +4,7 @@
//this is the only part of an EQStream that is seen by the application.
#include <string>
#include "client_version.h" // inv2 watch
#include "emu_versions.h"
typedef enum {
ESTABLISHED,
+11 -2
View File
@@ -19,11 +19,11 @@
#ifndef EQEMU_LOGSYS_H
#define EQEMU_LOGSYS_H
#include <fmt/format.h>
#include <iostream>
#include <fstream>
#include <stdio.h>
#include <functional>
#include "types.h"
namespace Logs {
@@ -83,6 +83,7 @@ namespace Logs {
Server_Client_Packet_With_Dump,
Client_Server_Packet_With_Dump,
Login_Server,
Client_Login,
MaxCategoryID /* Don't Remove this*/
};
@@ -131,7 +132,8 @@ namespace Logs {
"Packet :: Client -> Server Unhandled",
"Packet :: Server -> Client (Dump)",
"Packet :: Client -> Server (Dump)",
"Login Server"
"Login Server",
"Client Login"
};
}
@@ -156,6 +158,13 @@ public:
void SetCurrentTimeStamp(char* time_stamp); /* Used in file logs to prepend a timestamp entry for logs */
void StartFileLogs(const std::string &log_name = ""); /* Used to declare the processes file log and to keep it open for later use */
template <typename... Args>
void OutF(Logs::DebugLevel debug_level, uint16 log_category, const char *fmt, const Args&... args)
{
std::string log_str = fmt::format(fmt, args...);
Out(debug_level, log_category, log_str);
}
/*
LogSettings Struct
+39
View File
@@ -0,0 +1,39 @@
#pragma once
#include <functional>
#include "event_loop.h"
namespace EQ {
class BackgroundTask
{
public:
typedef std::function<void(void)> BackgroundTaskFunction;
struct BackgroundTaskBaton
{
BackgroundTaskFunction fn;
BackgroundTaskFunction on_finish;
};
BackgroundTask(BackgroundTaskFunction fn, BackgroundTaskFunction on_finish) {
uv_work_t *m_work = new uv_work_t;
memset(m_work, 0, sizeof(uv_work_t));
BackgroundTaskBaton *baton = new BackgroundTaskBaton();
baton->fn = fn;
baton->on_finish = on_finish;
m_work->data = baton;
uv_queue_work(EventLoop::Get().Handle(), m_work, [](uv_work_t* req) {
BackgroundTaskBaton *baton = (BackgroundTaskBaton*)req->data;
baton->fn();
}, [](uv_work_t* req, int status) {
BackgroundTaskBaton *baton = (BackgroundTaskBaton*)req->data;
baton->on_finish();
delete baton;
delete req;
});
}
~BackgroundTask() {
}
};
}
+36
View File
@@ -0,0 +1,36 @@
#pragma once
#include <functional>
#include <uv.h>
namespace EQ
{
class EventLoop
{
public:
static EventLoop &Get() {
static EventLoop inst;
return inst;
}
~EventLoop() {
uv_loop_close(&m_loop);
}
void Process() {
uv_run(&m_loop, UV_RUN_NOWAIT);
}
uv_loop_t* Handle() { return &m_loop; }
private:
EventLoop() {
memset(&m_loop, 0, sizeof(uv_loop_t));
uv_loop_init(&m_loop);
}
EventLoop(const EventLoop&);
EventLoop& operator=(const EventLoop&);
uv_loop_t m_loop;
};
}
+63
View File
@@ -0,0 +1,63 @@
#pragma once
#include <functional>
#include "event_loop.h"
namespace EQ {
class Timer
{
public:
Timer(uint64_t duration_ms, bool repeats, std::function<void(void)> cb)
{
memset(&m_timer, 0, sizeof(uv_timer_t));
m_cb = cb;
m_duration_ms = duration_ms;
m_repeats = repeats;
m_attached = nullptr;
Attach(EventLoop::Get().Handle());
}
~Timer()
{
Detach();
}
private:
void Execute() {
m_cb();
}
virtual void Attach(uv_loop_t *loop) {
if (!m_attached) {
uv_timer_init(loop, &m_timer);
m_timer.data = this;
if (m_repeats) {
uv_timer_start(&m_timer, [](uv_timer_t *handle) {
Timer *t = (Timer*)handle->data;
t->Execute();
}, m_duration_ms, m_duration_ms);
}
else {
uv_timer_start(&m_timer, [](uv_timer_t *handle) {
Timer *t = (Timer*)handle->data;
t->Execute();
}, m_duration_ms, 0);
}
m_attached = loop;
}
}
virtual void Detach() {
if (m_attached) {
uv_timer_stop(&m_timer);
m_attached = nullptr;
}
}
uv_timer_t m_timer;
std::function<void(void)> m_cb;
uint64_t m_duration_ms;
bool m_repeats;
uv_loop_t *m_attached;
};
}
+1 -1
View File
@@ -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 */
uint32 pet_items[EQEmu::legacy::MaterialCount]; /* Not Used */
EQEmu::TextureShortProfile pet_items; /* Not Used */
char merc_name[64]; /* Used */
uint32 aa_effects; /* Used */
+2 -2
View File
@@ -213,8 +213,8 @@ enum { //some random constants
#define MAX_NPC_FACTIONS 20
//individual faction pool
#define MAX_PERSONAL_FACTION 1200
#define MIN_PERSONAL_FACTION -3000
#define MAX_PERSONAL_FACTION 2000
#define MIN_PERSONAL_FACTION -2000
//The Level Cap:
//#define LEVEL_CAP RuleI(Character, MaxLevel) //hard cap is 127
-147
View File
@@ -1,147 +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_version.h"
bool EQEmu::versions::IsValidInventoryVersion(InventoryVersion inventory_version)
{
if (inventory_version <= InventoryVersion::Unknown || inventory_version > LastInventoryVersion)
return false;
return true;
}
bool EQEmu::versions::IsValidPCInventoryVersion(InventoryVersion inventory_version)
{
if (inventory_version <= InventoryVersion::Unknown || inventory_version > LastPCInventoryVersion)
return false;
return true;
}
bool EQEmu::versions::IsValidNonPCInventoryVersion(InventoryVersion inventory_version)
{
if (inventory_version <= LastPCInventoryVersion || inventory_version > LastNonPCInventoryVersion)
return false;
return true;
}
EQEmu::versions::InventoryVersion EQEmu::versions::ValidateInventoryVersion(InventoryVersion inventory_version)
{
if (inventory_version <= InventoryVersion::Unknown || inventory_version > LastInventoryVersion)
return InventoryVersion::Unknown;
return inventory_version;
}
EQEmu::versions::InventoryVersion EQEmu::versions::ValidatePCInventoryVersion(InventoryVersion inventory_version)
{
if (inventory_version <= InventoryVersion::Unknown || inventory_version > LastPCInventoryVersion)
return InventoryVersion::Unknown;
return inventory_version;
}
EQEmu::versions::InventoryVersion EQEmu::versions::ValidateNonPCInventoryVersion(InventoryVersion inventory_version)
{
if (inventory_version <= LastPCInventoryVersion || inventory_version > LastNonPCInventoryVersion)
return InventoryVersion::Unknown;
return inventory_version;
}
const char* EQEmu::versions::InventoryVersionName(InventoryVersion inventory_version)
{
switch (inventory_version) {
case InventoryVersion::Unknown:
return "Unknown Version";
case InventoryVersion::Client62:
return "Client 6.2";
case InventoryVersion::Titanium:
return "Titanium";
case InventoryVersion::SoF:
return "SoF";
case InventoryVersion::SoD:
return "SoD";
case InventoryVersion::UF:
return "UF";
case InventoryVersion::RoF:
return "RoF";
case InventoryVersion::RoF2:
return "RoF2";
case InventoryVersion::NPC:
return "NPC";
case InventoryVersion::Merc:
return "Merc";
case InventoryVersion::Bot:
return "Bot";
case InventoryVersion::Pet:
return "Pet";
default:
return "Invalid Version";
};
}
EQEmu::versions::ClientVersion EQEmu::versions::ConvertInventoryVersionToClientVersion(InventoryVersion inventory_version)
{
switch (inventory_version) {
case InventoryVersion::Unknown:
case InventoryVersion::Client62:
return ClientVersion::Unknown;
case InventoryVersion::Titanium:
return ClientVersion::Titanium;
case InventoryVersion::SoF:
return ClientVersion::SoF;
case InventoryVersion::SoD:
return ClientVersion::SoD;
case InventoryVersion::UF:
return ClientVersion::UF;
case InventoryVersion::RoF:
return ClientVersion::RoF;
case InventoryVersion::RoF2:
return ClientVersion::RoF2;
default:
return ClientVersion::Unknown;
}
}
EQEmu::versions::InventoryVersion EQEmu::versions::ConvertClientVersionToInventoryVersion(ClientVersion client_version)
{
switch (client_version) {
case ClientVersion::Unknown:
case ClientVersion::Client62:
return InventoryVersion::Unknown;
case ClientVersion::Titanium:
return InventoryVersion::Titanium;
case ClientVersion::SoF:
return InventoryVersion::SoF;
case ClientVersion::SoD:
return InventoryVersion::SoD;
case ClientVersion::UF:
return InventoryVersion::UF;
case ClientVersion::RoF:
return InventoryVersion::RoF;
case ClientVersion::RoF2:
return InventoryVersion::RoF2;
default:
return InventoryVersion::Unknown;
}
}
-63
View File
@@ -1,63 +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_VERSION_H
#define COMMON_INVENTORY_VERSION_H
#include "client_version.h"
namespace EQEmu
{
namespace versions {
enum class InventoryVersion {
Unknown = 0,
Client62,
Titanium,
SoF,
SoD,
UF,
RoF,
RoF2,
NPC,
Merc,
Bot,
Pet
};
static const InventoryVersion LastInventoryVersion = InventoryVersion::Pet;
static const InventoryVersion LastPCInventoryVersion = InventoryVersion::RoF2;
static const InventoryVersion LastNonPCInventoryVersion = InventoryVersion::Pet;
static const size_t InventoryVersionCount = (static_cast<size_t>(LastInventoryVersion) + 1);
extern bool IsValidInventoryVersion(InventoryVersion inventory_version);
extern bool IsValidPCInventoryVersion(InventoryVersion inventory_version);
extern bool IsValidNonPCInventoryVersion(InventoryVersion inventory_version);
extern InventoryVersion ValidateInventoryVersion(InventoryVersion inventory_version);
extern InventoryVersion ValidatePCInventoryVersion(InventoryVersion inventory_version);
extern InventoryVersion ValidateNonPCInventoryVersion(InventoryVersion inventory_version);
extern const char* InventoryVersionName(InventoryVersion inventory_version);
extern ClientVersion ConvertInventoryVersionToClientVersion(InventoryVersion inventory_version);
extern InventoryVersion ConvertClientVersionToInventoryVersion(ClientVersion client_version);
} /*versions*/
} /*EQEmu*/
#endif /*COMMON_INVENTORY_VERSION_H*/
+37 -34
View File
@@ -370,7 +370,7 @@ ItemInst* Inventory::PopItem(int16 slot_id)
return p;
}
bool Inventory::HasSpaceForItem(const EQEmu::Item_Struct *ItemToTry, int16 Quantity) {
bool Inventory::HasSpaceForItem(const EQEmu::ItemBase *ItemToTry, int16 Quantity) {
if (ItemToTry->Stackable) {
@@ -852,23 +852,23 @@ int16 Inventory::CalcSlotFromMaterial(uint8 material)
{
switch (material)
{
case EQEmu::legacy::MaterialHead:
case EQEmu::textures::TextureHead:
return EQEmu::legacy::SlotHead;
case EQEmu::legacy::MaterialChest:
case EQEmu::textures::TextureChest:
return EQEmu::legacy::SlotChest;
case EQEmu::legacy::MaterialArms:
case EQEmu::textures::TextureArms:
return EQEmu::legacy::SlotArms;
case EQEmu::legacy::MaterialWrist:
case EQEmu::textures::TextureWrist:
return EQEmu::legacy::SlotWrist1; // there's 2 bracers, only one bracer material
case EQEmu::legacy::MaterialHands:
case EQEmu::textures::TextureHands:
return EQEmu::legacy::SlotHands;
case EQEmu::legacy::MaterialLegs:
case EQEmu::textures::TextureLegs:
return EQEmu::legacy::SlotLegs;
case EQEmu::legacy::MaterialFeet:
case EQEmu::textures::TextureFeet:
return EQEmu::legacy::SlotFeet;
case EQEmu::legacy::MaterialPrimary:
case EQEmu::textures::TexturePrimary:
return EQEmu::legacy::SlotPrimary;
case EQEmu::legacy::MaterialSecondary:
case EQEmu::textures::TextureSecondary:
return EQEmu::legacy::SlotSecondary;
default:
return INVALID_INDEX;
@@ -880,30 +880,30 @@ uint8 Inventory::CalcMaterialFromSlot(int16 equipslot)
switch (equipslot)
{
case EQEmu::legacy::SlotHead:
return EQEmu::legacy::MaterialHead;
return EQEmu::textures::TextureHead;
case EQEmu::legacy::SlotChest:
return EQEmu::legacy::MaterialChest;
return EQEmu::textures::TextureChest;
case EQEmu::legacy::SlotArms:
return EQEmu::legacy::MaterialArms;
return EQEmu::textures::TextureArms;
case EQEmu::legacy::SlotWrist1:
//case SLOT_BRACER02: // non-live behavior
return EQEmu::legacy::MaterialWrist;
return EQEmu::textures::TextureWrist;
case EQEmu::legacy::SlotHands:
return EQEmu::legacy::MaterialHands;
return EQEmu::textures::TextureHands;
case EQEmu::legacy::SlotLegs:
return EQEmu::legacy::MaterialLegs;
return EQEmu::textures::TextureLegs;
case EQEmu::legacy::SlotFeet:
return EQEmu::legacy::MaterialFeet;
return EQEmu::textures::TextureFeet;
case EQEmu::legacy::SlotPrimary:
return EQEmu::legacy::MaterialPrimary;
return EQEmu::textures::TexturePrimary;
case EQEmu::legacy::SlotSecondary:
return EQEmu::legacy::MaterialSecondary;
return EQEmu::textures::TextureSecondary;
default:
return EQEmu::legacy::MaterialInvalid;
return EQEmu::textures::TextureInvalid;
}
}
bool Inventory::CanItemFitInContainer(const EQEmu::Item_Struct *ItemToTry, const EQEmu::Item_Struct *Container) {
bool Inventory::CanItemFitInContainer(const EQEmu::ItemBase *ItemToTry, const EQEmu::ItemBase *Container) {
if (!ItemToTry || !Container)
return false;
@@ -929,7 +929,7 @@ bool Inventory::SupportsClickCasting(int16 slot_id)
}
else if (slot_id >= EQEmu::legacy::GENERAL_BAGS_BEGIN && slot_id <= EQEmu::legacy::GENERAL_BAGS_END)
{
if (EQEmu::inventory::AllowClickCastFromBag(m_inventory_version))
if (EQEmu::inventory::Lookup(m_inventory_version)->AllowClickCastFromBag)
return true;
}
@@ -1440,10 +1440,10 @@ int16 Inventory::_HasItemByLoreGroup(ItemInstQueue& iqueue, uint32 loregroup)
//
// class ItemInst
//
ItemInst::ItemInst(const EQEmu::Item_Struct* item, int16 charges) {
ItemInst::ItemInst(const EQEmu::ItemBase* item, int16 charges) {
m_use_type = ItemInstNormal;
if(item) {
m_item = new EQEmu::Item_Struct(*item);
m_item = new EQEmu::ItemBase(*item);
} else {
m_item = nullptr;
}
@@ -1474,7 +1474,7 @@ ItemInst::ItemInst(SharedDatabase *db, uint32 item_id, int16 charges) {
m_use_type = ItemInstNormal;
m_item = db->GetItem(item_id);
if(m_item) {
m_item = new EQEmu::Item_Struct(*m_item);
m_item = new EQEmu::ItemBase(*m_item);
}
else {
m_item = nullptr;
@@ -1529,7 +1529,7 @@ ItemInst::ItemInst(const ItemInst& copy)
{
m_use_type=copy.m_use_type;
if(copy.m_item)
m_item = new EQEmu::Item_Struct(*copy.m_item);
m_item = new EQEmu::ItemBase(*copy.m_item);
else
m_item = nullptr;
@@ -1565,7 +1565,7 @@ ItemInst::ItemInst(const ItemInst& copy)
m_evolveLvl = copy.m_evolveLvl;
m_activated = copy.m_activated;
if (copy.m_scaledItem)
m_scaledItem = new EQEmu::Item_Struct(*copy.m_scaledItem);
m_scaledItem = new EQEmu::ItemBase(*copy.m_scaledItem);
else
m_scaledItem = nullptr;
@@ -1800,7 +1800,7 @@ void ItemInst::ClearByFlags(byFlagSetting is_nodrop, byFlagSetting is_norent)
continue;
}
const EQEmu::Item_Struct* item = inst->GetItem();
const EQEmu::ItemBase* item = inst->GetItem();
if (item == nullptr) {
cur = m_contents.erase(cur);
continue;
@@ -1863,6 +1863,9 @@ uint8 ItemInst::FirstOpenSlot() const
uint8 ItemInst::GetTotalItemCount() const
{
if (!m_item)
return 0;
uint8 item_count = 1;
if (m_item && !m_item->IsClassBag()) { return item_count; }
@@ -1941,7 +1944,7 @@ bool ItemInst::UpdateOrnamentationInfo() {
int32 ornamentationAugtype = RuleI(Character, OrnamentationAugmentType);
if (GetOrnamentationAug(ornamentationAugtype))
{
const EQEmu::Item_Struct* ornamentItem;
const EQEmu::ItemBase* ornamentItem;
ornamentItem = GetOrnamentationAug(ornamentationAugtype)->GetItem();
if (ornamentItem != nullptr)
{
@@ -1968,7 +1971,7 @@ bool ItemInst::UpdateOrnamentationInfo() {
return ornamentSet;
}
bool ItemInst::CanTransform(const EQEmu::Item_Struct *ItemToTry, const EQEmu::Item_Struct *Container, bool AllowAll) {
bool ItemInst::CanTransform(const EQEmu::ItemBase *ItemToTry, const EQEmu::ItemBase *Container, bool AllowAll) {
if (!ItemToTry || !Container) return false;
if (ItemToTry->ItemType == EQEmu::item::ItemTypeArrow || strnlen(Container->CharmFile, 30) == 0)
@@ -2102,7 +2105,7 @@ bool ItemInst::IsAmmo() const
}
const EQEmu::Item_Struct* ItemInst::GetItem() const
const EQEmu::ItemBase* ItemInst::GetItem() const
{
if (!m_item)
return nullptr;
@@ -2113,7 +2116,7 @@ const EQEmu::Item_Struct* ItemInst::GetItem() const
return m_item;
}
const EQEmu::Item_Struct* ItemInst::GetUnscaledItem() const
const EQEmu::ItemBase* ItemInst::GetUnscaledItem() const
{
// No operator calls and defaults to nullptr
return m_item;
@@ -2221,10 +2224,10 @@ void ItemInst::ScaleItem() {
return;
if (m_scaledItem) {
memcpy(m_scaledItem, m_item, sizeof(EQEmu::Item_Struct));
memcpy(m_scaledItem, m_item, sizeof(EQEmu::ItemBase));
}
else {
m_scaledItem = new EQEmu::Item_Struct(*m_item);
m_scaledItem = new EQEmu::ItemBase(*m_item);
}
float Mult = (float)(GetExp()) / 10000; // scaling is determined by exp, with 10,000 being full stats
+11 -13
View File
@@ -29,16 +29,14 @@ class ItemParse; // Parses item packets
class EvolveInfo; // Stores information about an evolving item family
#include "../common/eq_constants.h"
#include "../common/item_struct.h"
#include "../common/item_base.h"
#include "../common/timer.h"
#include "../common/bodytypes.h"
#include "../common/deity.h" // aren't we already in '/common'?
#include "string_util.h"
#include "../common/deity.h"
#include "../common/memory_buffer.h"
#include <list>
#include <map>
//#include <sstream>
namespace ItemField
@@ -177,7 +175,7 @@ public:
ItemInst* PopItem(int16 slot_id);
// Check whether there is space for the specified number of the specified item.
bool HasSpaceForItem(const EQEmu::Item_Struct *ItemToTry, int16 Quantity);
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
@@ -202,7 +200,7 @@ public:
static int16 CalcSlotFromMaterial(uint8 material);
static uint8 CalcMaterialFromSlot(int16 equipslot);
static bool CanItemFitInContainer(const EQEmu::Item_Struct *ItemToTry, const EQEmu::Item_Struct *Container);
static bool CanItemFitInContainer(const EQEmu::ItemBase *ItemToTry, const EQEmu::ItemBase *Container);
// Test for valid inventory casting slot
bool SupportsClickCasting(int16 slot_id);
@@ -279,7 +277,7 @@ public:
/////////////////////////
// Constructors/Destructor
ItemInst(const EQEmu::Item_Struct* item = nullptr, int16 charges = 0);
ItemInst(const EQEmu::ItemBase* item = nullptr, int16 charges = 0);
ItemInst(SharedDatabase *db, uint32 item_id, int16 charges = 0);
@@ -348,7 +346,7 @@ public:
bool IsAugmented();
ItemInst* GetOrnamentationAug(int32 ornamentationAugtype) const;
bool UpdateOrnamentationInfo();
static bool CanTransform(const EQEmu::Item_Struct *ItemToTry, const EQEmu::Item_Struct *Container, bool AllowAll = false);
static bool CanTransform(const EQEmu::ItemBase *ItemToTry, const EQEmu::ItemBase *Container, bool AllowAll = false);
// Has attack/delay?
bool IsWeapon() const;
@@ -357,8 +355,8 @@ public:
// 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::Item_Struct* GetItem() const;
const EQEmu::Item_Struct* GetUnscaledItem() const;
const EQEmu::ItemBase* GetItem() const;
const EQEmu::ItemBase* GetUnscaledItem() const;
int16 GetCharges() const { return m_charges; }
void SetCharges(int16 charges) { m_charges = charges; }
@@ -502,7 +500,7 @@ protected:
void _PutItem(uint8 index, ItemInst* inst) { m_contents[index] = inst; }
ItemInstTypes m_use_type; // Usage type for item
const EQEmu::Item_Struct* m_item; // Ptr to item data
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;
@@ -514,7 +512,7 @@ protected:
uint32 m_exp;
int8 m_evolveLvl;
bool m_activated;
EQEmu::Item_Struct* m_scaledItem;
EQEmu::ItemBase* m_scaledItem;
EvolveInfo* m_evolveInfo;
bool m_scaling;
uint32 m_ornamenticon;
@@ -17,7 +17,7 @@
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "item_struct.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::Item_Struct::IsEquipable(uint16 race_id, uint16 class_id)
bool EQEmu::ItemBase::IsEquipable(uint16 race_id, uint16 class_id)
{
if (!(Races & GetPlayerRaceBit(race_id)))
return false;
@@ -178,32 +178,32 @@ bool EQEmu::Item_Struct::IsEquipable(uint16 race_id, uint16 class_id)
return true;
}
bool EQEmu::Item_Struct::IsClassCommon()
bool EQEmu::ItemBase::IsClassCommon()
{
return (ItemClass == item::ItemClassCommon);
}
bool EQEmu::Item_Struct::IsClassBag()
bool EQEmu::ItemBase::IsClassBag()
{
return (ItemClass == item::ItemClassBag);
}
bool EQEmu::Item_Struct::IsClassBook()
bool EQEmu::ItemBase::IsClassBook()
{
return (ItemClass == item::ItemClassBook);
}
bool EQEmu::Item_Struct::IsType1HWeapon()
bool EQEmu::ItemBase::IsType1HWeapon()
{
return ((ItemType == item::ItemType1HBlunt) || (ItemType == item::ItemType1HSlash) || (ItemType == item::ItemType1HPiercing));
}
bool EQEmu::Item_Struct::IsType2HWeapon()
bool EQEmu::ItemBase::IsType2HWeapon()
{
return ((ItemType == item::ItemType2HBlunt) || (ItemType == item::ItemType2HSlash) || (ItemType == item::ItemType2HPiercing));
}
bool EQEmu::Item_Struct::IsTypeShield()
bool EQEmu::ItemBase::IsTypeShield()
{
return (ItemType == item::ItemTypeShield);
}
+16 -16
View File
@@ -17,8 +17,8 @@
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 04111-1307 USA
*/
#ifndef COMMON_ITEM_STRUCT_H
#define COMMON_ITEM_STRUCT_H
#ifndef COMMON_ITEM_BASE_H
#define COMMON_ITEM_BASE_H
/*
@@ -336,10 +336,10 @@ namespace EQEmu
};
enum ItemDataType : uint8 {
ItemDataTypeBase = 0,
ItemDataTypeScaling,
ItemDataTypeEvolving,
ItemDataTypeCount
ItemDataBase = 0,
ItemDataScaling,
ItemDataEvolving,
ItemDataCount
};
struct ItemEffect_Struct {
@@ -364,10 +364,10 @@ namespace EQEmu
const void * inst;
};
struct Item_Struct {
struct ItemBase {
// Non packet based fields
uint8 MinStatus;
//uint8 ItemDataType;
uint8 ItemDataType; // memset to item::ItemDataBase ('0') during mmf load
// Packet based fields
uint8 ItemClass; // Item Type: 0=common, 1=container, 2=book
@@ -551,15 +551,15 @@ namespace EQEmu
bool IsType2HWeapon();
bool IsTypeShield();
bool IsEquipable(uint16 Race, uint16 Class) const { return const_cast<Item_Struct*>(this)->IsEquipable(Race, Class); }
bool IsClassCommon() const { return const_cast<Item_Struct*>(this)->IsClassCommon(); }
bool IsClassBag() const { return const_cast<Item_Struct*>(this)->IsClassBag(); }
bool IsClassBook() const { return const_cast<Item_Struct*>(this)->IsClassBook(); }
bool IsType1HWeapon() const { return const_cast<Item_Struct*>(this)->IsType1HWeapon(); }
bool IsType2HWeapon() const { return const_cast<Item_Struct*>(this)->IsType2HWeapon(); }
bool IsTypeShield() const { return const_cast<Item_Struct*>(this)->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_STRUCT_H*/
#endif /*COMMON_ITEM_BASE_H*/
+4 -4
View File
@@ -10,7 +10,7 @@
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.
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
@@ -82,14 +82,14 @@ bool EQEmu::lightsource::IsLevelGreater(uint8 left_type, uint8 right_type)
return (light_levels[left_type] > light_levels[right_type]);
}
EQEmu::lightsource::Light_Struct::Light_Struct()
EQEmu::LightSource_Struct::LightSource_Struct()
{
Clear();
}
void EQEmu::lightsource::Light_Struct::Clear()
void EQEmu::LightSource_Struct::Clear()
{
memset(&Slot, 0, (sizeof(uint8) * sizeof(Slot)));
memset(&Slot, 0, (sizeof(uint8) * lightsource::LightCount));
}
void EQEmu::LightSourceProfile::Clear()
+13 -14
View File
@@ -10,7 +10,7 @@
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.
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
@@ -34,7 +34,6 @@ namespace EQEmu
LightCount
};
enum LightType {
LightTypeNone = 0,
LightTypeCandle,
@@ -70,21 +69,21 @@ namespace EQEmu
LightLevelCount
};
struct Light_Struct {
uint8 Slot[LightCount];
Light_Struct();
void Clear();
inline uint8& operator[](LightSlot index) { return Slot[index]; }
};
extern uint8 TypeToLevel(uint8 light_type);
extern bool IsLevelGreater(uint8 left_type, uint8 right_type);
}; /*lightsource*/
struct LightSource_Struct {
uint8 Slot[lightsource::LightCount];
LightSource_Struct();
void Clear();
inline uint8& operator[](lightsource::LightSlot index) { return Slot[index]; }
};
struct LightSourceProfile {
/*
Current criteria (light types):
@@ -103,8 +102,8 @@ namespace EQEmu
-- The timer-based update cancels out the invalid light source
*/
lightsource::Light_Struct Type; // Light types (classifications)
lightsource::Light_Struct Level; // Light levels (intensities) - used to determine which light source should be active
LightSource_Struct Type; // Light types (classifications)
LightSource_Struct Level; // Light levels (intensities) - used to determine which light source should be active
LightSourceProfile() { }
+277
View File
@@ -0,0 +1,277 @@
/* 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 "memory_buffer.h"
EQEmu::MemoryBuffer::MemoryBuffer()
{
buffer_ = nullptr;
size_ = 0;
capacity_ = 0;
read_pos_ = 0;
write_pos_ = 0;
}
EQEmu::MemoryBuffer::MemoryBuffer(size_t sz)
{
buffer_ = nullptr;
size_ = 0;
capacity_ = 0;
read_pos_ = 0;
write_pos_ = 0;
Resize(sz);
}
EQEmu::MemoryBuffer::MemoryBuffer(const MemoryBuffer &other)
{
if(other.capacity_) {
buffer_ = new uchar[other.capacity_];
memcpy(buffer_, other.buffer_, other.capacity_);
} else {
buffer_ = nullptr;
}
size_ = other.size_;
capacity_ = other.capacity_;
write_pos_ = other.write_pos_;
read_pos_ = other.read_pos_;
}
EQEmu::MemoryBuffer::MemoryBuffer(MemoryBuffer &&other)
{
uchar *tbuf = other.buffer_;
size_t tsz = other.size_;
size_t tcapacity = other.capacity_;
size_t twrite_pos = other.write_pos_;
size_t tread_pos = other.read_pos_;
other.buffer_ = nullptr;
other.size_ = 0;
other.capacity_ = 0;
other.read_pos_ = 0;
other.write_pos_ = 0;
buffer_ = tbuf;
size_ = tsz;
capacity_ = tcapacity;
write_pos_ = twrite_pos;
read_pos_ = tread_pos;
}
EQEmu::MemoryBuffer& EQEmu::MemoryBuffer::operator=(const MemoryBuffer &other)
{
if(this == &other) {
return *this;
}
if(buffer_) {
delete[] buffer_;
}
if(other.capacity_) {
buffer_ = new uchar[other.capacity_];
memcpy(buffer_, other.buffer_, other.capacity_);
}
else {
buffer_ = nullptr;
}
size_ = other.size_;
capacity_ = other.capacity_;
write_pos_ = other.write_pos_;
read_pos_ = other.read_pos_;
return *this;
}
EQEmu::MemoryBuffer& EQEmu::MemoryBuffer::operator=(MemoryBuffer &&other)
{
uchar *tbuf = other.buffer_;
size_t tsz = other.size_;
size_t tcapacity = other.capacity_;
size_t twrite_pos = other.write_pos_;
size_t tread_pos = other.read_pos_;
other.buffer_ = nullptr;
other.size_ = 0;
other.capacity_ = 0;
other.read_pos_ = 0;
other.write_pos_ = 0;
buffer_ = tbuf;
size_ = tsz;
capacity_ = tcapacity;
write_pos_ = twrite_pos;
read_pos_ = tread_pos;
return *this;
}
EQEmu::MemoryBuffer& EQEmu::MemoryBuffer::operator+=(const MemoryBuffer &rhs)
{
if(!rhs.buffer_) {
return *this;
}
if(buffer_) {
size_t old_size = size_;
Resize(size_ + rhs.size_);
memcpy(&buffer_[old_size], rhs.buffer_, rhs.size_);
} else {
buffer_ = new uchar[rhs.capacity_];
memcpy(buffer_, rhs.buffer_, rhs.capacity_);
size_ = rhs.size_;
capacity_ = rhs.capacity_;
}
return *this;
}
EQEmu::MemoryBuffer::~MemoryBuffer()
{
Clear();
}
uchar& EQEmu::MemoryBuffer::operator[](size_t pos)
{
return buffer_[pos];
}
const uchar& EQEmu::MemoryBuffer::operator[](size_t pos) const
{
return buffer_[pos];
}
bool EQEmu::MemoryBuffer::Empty()
{
return size_ == 0;
}
bool EQEmu::MemoryBuffer::Empty() const
{
return size_ == 0;
}
size_t EQEmu::MemoryBuffer::Size()
{
return size_;
}
size_t EQEmu::MemoryBuffer::Size() const
{
return size_;
}
size_t EQEmu::MemoryBuffer::Capacity()
{
return capacity_;
}
size_t EQEmu::MemoryBuffer::Capacity() const
{
return capacity_;
}
void EQEmu::MemoryBuffer::Resize(size_t sz)
{
if(!buffer_) {
size_t new_size = sz + 64;
buffer_ = new uchar[new_size];
capacity_ = new_size;
size_ = sz;
memset(buffer_, 0, capacity_);
return;
}
if(sz > capacity_) {
size_t new_size = sz + 32;
uchar *temp = new uchar[new_size];
memcpy(temp, buffer_, capacity_);
delete[] buffer_;
buffer_ = temp;
capacity_ = new_size;
size_ = sz;
}
else {
size_ = sz;
}
}
void EQEmu::MemoryBuffer::Clear()
{
if(buffer_) {
delete[] buffer_;
buffer_ = nullptr;
}
size_ = 0;
capacity_ = 0;
write_pos_ = 0;
read_pos_ = 0;
}
void EQEmu::MemoryBuffer::Zero()
{
if(buffer_) {
memset(buffer_, 0, capacity_);
}
}
void EQEmu::MemoryBuffer::Write(const char *val, size_t len)
{
size_t size_needed = write_pos_ + len;
Resize(size_needed);
memcpy(&buffer_[write_pos_], val, len);
write_pos_ += len;
}
void EQEmu::MemoryBuffer::Read(uchar *buf, size_t len)
{
memcpy(buf, &buffer_[read_pos_], len);
read_pos_ += len;
}
void EQEmu::MemoryBuffer::Read(char *str)
{
size_t len = strlen((const char*)&buffer_[read_pos_]);
memcpy(str, &buffer_[read_pos_], len);
read_pos_ += len;
}
void EQEmu::OutBuffer::overwrite(OutBuffer::pos_type position, const char *_Str, std::streamsize _Count)
{
auto last_pos = tellp();
seekp(position);
write(_Str, _Count);
seekp(last_pos);
}
uchar* EQEmu::OutBuffer::detach()
{
size_t buffer_size = tellp();
if (buffer_size == 0)
return nullptr;
auto out_buffer = new uchar[buffer_size];
memcpy(out_buffer, str().c_str(), buffer_size);
flush();
return out_buffer;
}
+134
View File
@@ -0,0 +1,134 @@
/* 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_MEMORY_BUFFER
#define COMMON_MEMORY_BUFFER
#include "types.h"
#include <type_traits>
#include <string.h>
#include <string>
#include <sstream>
namespace EQEmu
{
class MemoryBuffer {
public:
MemoryBuffer();
MemoryBuffer(size_t sz);
MemoryBuffer(const MemoryBuffer &other);
MemoryBuffer(MemoryBuffer &&other);
MemoryBuffer& operator=(const MemoryBuffer &other);
MemoryBuffer& operator=(MemoryBuffer &&other);
MemoryBuffer& operator+=(const MemoryBuffer &rhs);
friend MemoryBuffer operator+(MemoryBuffer lhs, const MemoryBuffer& rhs) { return lhs += rhs; }
~MemoryBuffer();
uchar& operator[](size_t pos);
const uchar& operator[](size_t pos) const;
template<typename T>
operator T*() {
return reinterpret_cast<T*>(buffer_);
}
template<typename T>
operator T*() const {
return reinterpret_cast<T*>(buffer_);
}
operator bool() { return buffer_ != nullptr; }
operator bool() const { return buffer_ != nullptr; }
bool Empty();
bool Empty() const;
size_t Size();
size_t Size() const;
size_t Capacity();
size_t Capacity() const;
void Resize(size_t sz);
void Clear();
void Zero();
template<typename T>
void Write(T val) {
static_assert(std::is_pod<T>::value, "MemoryBuffer::Write<T>(T val) only works on pod and string types.");
Write((const char*)&val, sizeof(T));
}
template<typename T>
T Read() {
static_assert(std::is_pod<T>::value, "MemoryBuffer::Read<T>() only works on pod and string types.");
T temp;
Read((uchar*)&temp, sizeof(T));
return temp;
}
void Write(const std::string &val) {
Write(val.c_str(), val.length());
Write((uint8)0);
}
void Write(const char *val) {
size_t len = strlen(val);
Write(val, len);
Write((uint8)0);
}
std::string ReadString() {
std::string ret;
size_t len = strlen((const char*)&buffer_[read_pos_]);
ret.resize(len);
memcpy(&ret[0], &buffer_[read_pos_], len);
read_pos_ += len + 1;
return ret;
}
void Write(const char *val, size_t len);
void Read(uchar *buf, size_t len);
void Read(char *str);
inline size_t GetWritePosition() { return write_pos_; }
inline void SetWritePosition(size_t wp) { write_pos_ = wp; }
inline void WriteSkipBytes(size_t skip) { write_pos_ += skip; }
inline size_t GetReadPosition() { return read_pos_; }
inline void SetReadPosition(size_t rp) { read_pos_ = rp; }
inline void ReadSkipBytes(size_t skip) { read_pos_ += skip; }
private:
uchar *buffer_;
size_t size_;
size_t capacity_;
size_t write_pos_;
size_t read_pos_;
};
class OutBuffer : public std::stringstream {
public:
inline size_t size() { return tellp(); }
void overwrite(OutBuffer::pos_type position, const char *_Str, std::streamsize _Count);
uchar* detach();
};
} /*EQEmu*/
#endif /*COMMON_MEMORY_BUFFER*/
+96
View File
@@ -0,0 +1,96 @@
#include "crc32.h"
#include <memory.h>
unsigned int CRC32EncodeTable[256] =
{
0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA,
0x076DC419, 0x706AF48F, 0xE963A535, 0x9E6495A3,
0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988,
0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91,
0x1DB71064, 0x6AB020F2, 0xF3B97148, 0x84BE41DE,
0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7,
0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC,
0x14015C4F, 0x63066CD9, 0xFA0F3D63, 0x8D080DF5,
0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172,
0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B,
0x35B5A8FA, 0x42B2986C, 0xDBBBC9D6, 0xACBCF940,
0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59,
0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116,
0x21B4F4B5, 0x56B3C423, 0xCFBA9599, 0xB8BDA50F,
0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924,
0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D,
0x76DC4190, 0x01DB7106, 0x98D220BC, 0xEFD5102A,
0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433,
0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818,
0x7F6A0DBB, 0x086D3D2D, 0x91646C97, 0xE6635C01,
0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E,
0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457,
0x65B0D9C6, 0x12B7E950, 0x8BBEB8EA, 0xFCB9887C,
0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65,
0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2,
0x4ADFA541, 0x3DD895D7, 0xA4D1C46D, 0xD3D6F4FB,
0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0,
0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9,
0x5005713C, 0x270241AA, 0xBE0B1010, 0xC90C2086,
0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F,
0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4,
0x59B33D17, 0x2EB40D81, 0xB7BD5C3B, 0xC0BA6CAD,
0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A,
0xEAD54739, 0x9DD277AF, 0x04DB2615, 0x73DC1683,
0xE3630B12, 0x94643B84, 0x0D6D6A3E, 0x7A6A5AA8,
0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1,
0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE,
0xF762575D, 0x806567CB, 0x196C3671, 0x6E6B06E7,
0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC,
0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5,
0xD6D6A3E8, 0xA1D1937E, 0x38D8C2C4, 0x4FDFF252,
0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B,
0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60,
0xDF60EFC3, 0xA867DF55, 0x316E8EEF, 0x4669BE79,
0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236,
0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F,
0xC5BA3BBE, 0xB2BD0B28, 0x2BB45A92, 0x5CB36A04,
0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D,
0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A,
0x9C0906A9, 0xEB0E363F, 0x72076785, 0x05005713,
0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38,
0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21,
0x86D3D2D4, 0xF1D4E242, 0x68DDB3F8, 0x1FDA836E,
0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777,
0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C,
0x8F659EFF, 0xF862AE69, 0x616BFFD3, 0x166CCF45,
0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2,
0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB,
0xAED16A4A, 0xD9D65ADC, 0x40DF0B66, 0x37D83BF0,
0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9,
0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6,
0xBAD03605, 0xCDD70693, 0x54DE5729, 0x23D967BF,
0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94,
0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D
};
int EQ::Crc32(const void * data, int size)
{
int crc = 0xffffffff;
auto buffer = (const uint8_t *)data;
for (int i = 0; i < size; ++i) {
crc = ((crc >> 8) & 0x00FFFFFFL) ^ CRC32EncodeTable[(crc ^ *&buffer[i]) & 0x000000FFL];
}
return ~crc;
}
int EQ::Crc32(const void * data, int size, int key)
{
int crc = 0xffffffff;
for (int i = 0; i < 4; ++i) {
crc = ((crc >> 8) & 0x00FFFFFFL) ^ CRC32EncodeTable[(crc ^ ((key >> (i * 8)) & 0xff)) & 0x000000FFL];
}
auto buffer = (const uint8_t *)data;
for (int i = 0; i < size; ++i) {
crc = ((crc >> 8) & 0x00FFFFFFL) ^ CRC32EncodeTable[(crc ^ *&buffer[i]) & 0x000000FFL];
}
return ~crc;
}
+9
View File
@@ -0,0 +1,9 @@
#pragma once
#include <stdint.h>
namespace EQ
{
int Crc32(const void *data, int size);
int Crc32(const void *data, int size, int key);
}
File diff suppressed because it is too large Load Diff
+271
View File
@@ -0,0 +1,271 @@
#pragma once
#include "../random.h"
#include "packet.h"
#include "daybreak_structs.h"
#include <uv.h>
#include <chrono>
#include <functional>
#include <memory>
#include <map>
#include <queue>
#include <list>
namespace EQ
{
namespace Net
{
enum DaybreakProtocolOpcode
{
OP_Padding = 0x00,
OP_SessionRequest = 0x01,
OP_SessionResponse = 0x02,
OP_Combined = 0x03,
OP_SessionDisconnect = 0x05,
OP_KeepAlive = 0x06,
OP_SessionStatRequest = 0x07,
OP_SessionStatResponse = 0x08,
OP_Packet = 0x09,
OP_Packet2 = 0x0a,
OP_Packet3 = 0x0b,
OP_Packet4 = 0x0c,
OP_Fragment = 0x0d,
OP_Fragment2 = 0x0e,
OP_Fragment3 = 0x0f,
OP_Fragment4 = 0x10,
OP_OutOfOrderAck = 0x11,
OP_OutOfOrderAck2 = 0x12,
OP_OutOfOrderAck3 = 0x13,
OP_OutOfOrderAck4 = 0x14,
OP_Ack = 0x15,
OP_Ack2 = 0x16,
OP_Ack3 = 0x17,
OP_Ack4 = 0x18,
OP_AppCombined = 0x19,
OP_OutboundPing = 0x1c,
OP_OutOfSession = 0x1d
};
enum DbProtocolStatus
{
StatusConnecting,
StatusConnected,
StatusDisconnecting,
StatusDisconnected
};
enum DaybreakEncodeType
{
EncodeNone = 0,
EncodeCompression = 1,
EncodeXOR = 4,
};
enum SequenceOrder
{
SequenceCurrent,
SequenceFuture,
SequencePast
};
typedef std::chrono::system_clock::time_point Timestamp;
typedef std::chrono::system_clock Clock;
struct DaybreakConnectionStats
{
DaybreakConnectionStats() {
recv_bytes = 0;
sent_bytes = 0;
recv_packets = 0;
sent_packets = 0;
total_ping = 0;
total_acks = 0;
min_ping = 0xFFFFFFFFFFFFFFFFUL;
max_ping = 0;
created = Clock::now();
}
uint64_t recv_bytes;
uint64_t sent_bytes;
uint64_t recv_packets;
uint64_t sent_packets;
uint64_t total_ping;
uint64_t total_acks;
uint64_t min_ping;
uint64_t max_ping;
Timestamp created;
};
class DaybreakConnectionManager;
class DaybreakConnection;
class DaybreakConnection
{
public:
DaybreakConnection(DaybreakConnectionManager *owner, const DaybreakConnect &connect, const std::string &endpoint, int port);
DaybreakConnection(DaybreakConnectionManager *owner, const std::string &endpoint, int port);
~DaybreakConnection();
const std::string& RemoteEndpoint() const { return m_endpoint; }
int RemotePort() const { return m_port; }
void QueuePacket(Packet &p);
void QueuePacket(Packet &p, int stream);
void QueuePacket(Packet &p, int stream, bool reliable);
const DaybreakConnectionStats& GetStats() const { return m_stats; }
void ResetStats();
size_t GetRollingPing() const { return m_rolling_ping; }
private:
DaybreakConnectionManager *m_owner;
std::string m_endpoint;
int m_port;
uint32_t m_connect_code;
uint32_t m_encode_key;
uint32_t m_max_packet_size;
uint32_t m_crc_bytes;
DaybreakEncodeType m_encode_passes[2];
Timestamp m_last_send;
Timestamp m_last_recv;
DbProtocolStatus m_status;
Timestamp m_hold_time;
std::list<WritablePacket> m_buffered_packets;
size_t m_buffered_packets_length;
Timestamp m_last_stats;
DaybreakConnectionStats m_stats;
Timestamp m_last_session_stats;
uint64_t m_last_session_stats_ping;
size_t m_resend_delay;
size_t m_rolling_ping;
struct DaybreakSentPacket
{
WritablePacket packet;
Timestamp last_sent;
Timestamp first_sent;
size_t times_resent;
};
struct DaybreakStream
{
DaybreakStream() {
sequence_in = 0;
sequence_out = 0;
fragment_current_bytes = 0;
fragment_total_bytes = 0;
}
uint16_t sequence_in;
uint16_t sequence_out;
std::map<uint16_t, Packet*> packet_queue;
WritablePacket fragment_packet;
uint32_t fragment_current_bytes;
uint32_t fragment_total_bytes;
std::map<uint16_t, DaybreakSentPacket> sent_packets;
};
DaybreakStream m_streams[4];
std::weak_ptr<DaybreakConnection> m_self;
void Process();
void ProcessPacket(Packet &p);
void ProcessQueue();
void RemoveFromQueue(int stream, uint16_t seq);
void AddToQueue(int stream, uint16_t seq, const Packet &p);
void ProcessDecodedPacket(const Packet &p);
void ChangeStatus(DbProtocolStatus new_status);
bool ValidateCRC(Packet &p);
void AppendCRC(Packet &p);
bool PacketCanBeEncoded(Packet &p) const;
void Decode(Packet &p, size_t offset, size_t length);
void Encode(Packet &p, size_t offset, size_t length);
void Decompress(Packet &p, size_t offset, size_t length);
void Compress(Packet &p, size_t offset, size_t length);
void ProcessResend();
void ProcessResend(int stream);
void Ack(int stream, uint16_t seq);
void OutOfOrderAck(int stream, uint16_t seq);
void SendConnect();
void SendKeepAlive();
void SendAck(int stream, uint16_t seq);
void SendOutOfOrderAck(int stream, uint16_t seq);
void SendStatSync();
void InternalBufferedSend(Packet &p);
void InternalSend(Packet &p);
void InternalQueuePacket(Packet &p, int stream_id, bool reliable);
void FlushBuffer();
SequenceOrder CompareSequence(uint16_t expected, uint16_t actual) const;
friend class DaybreakConnectionManager;
};
struct DaybreakConnectionManagerOptions
{
DaybreakConnectionManagerOptions() {
max_connection_count = 0;
keepalive_delay_ms = 0;
resend_delay_ms = 1000;
stats_delay_ms = 10000;
connect_delay_ms = 1000;
stale_connection_ms = 60000;
crc_length = 2;
max_packet_size = 512;
encode_passes[0] = DaybreakEncodeType::EncodeNone;
encode_passes[1] = DaybreakEncodeType::EncodeNone;
port = 0;
hold_size = 384;
hold_length_ms = 50;
}
size_t max_packet_size;
size_t max_connection_count;
size_t keepalive_delay_ms;
size_t resend_delay_ms;
size_t stats_delay_ms;
size_t connect_delay_ms;
size_t stale_connection_ms;
size_t crc_length;
size_t hold_size;
size_t hold_length_ms;
DaybreakEncodeType encode_passes[2];
int port;
};
class DaybreakConnectionManager
{
public:
DaybreakConnectionManager();
DaybreakConnectionManager(const DaybreakConnectionManagerOptions &opts);
~DaybreakConnectionManager();
void Connect(const std::string &addr, int port);
void Process();
void ProcessResend();
void OnNewConnection(std::function<void(std::shared_ptr<DaybreakConnection>)> func) { m_on_new_connection = func; }
void OnConnectionStateChange(std::function<void(std::shared_ptr<DaybreakConnection>, DbProtocolStatus, DbProtocolStatus)> func) { m_on_connection_state_change = func; }
void OnPacketRecv(std::function<void(std::shared_ptr<DaybreakConnection>, const Packet &)> func) { m_on_packet_recv = func; }
private:
void Attach(uv_loop_t *loop);
void Detach();
EQEmu::Random m_rand;
uv_timer_t m_timer;
uv_timer_t m_resend_timer;
uv_udp_t m_socket;
uv_loop_t *m_attached;
DaybreakConnectionManagerOptions m_options;
std::function<void(std::shared_ptr<DaybreakConnection>)> m_on_new_connection;
std::function<void(std::shared_ptr<DaybreakConnection>, DbProtocolStatus, DbProtocolStatus)> m_on_connection_state_change;
std::function<void(std::shared_ptr<DaybreakConnection>, const Packet&)> m_on_packet_recv;
std::map<std::pair<std::string, int>, std::shared_ptr<DaybreakConnection>> m_connections;
void ProcessPacket(const std::string &endpoint, int port, const char *data, size_t size);
std::shared_ptr<DaybreakConnection> FindConnectionByEndpoint(std::string addr, int port);
void SendSessionLost(const std::string &addr, int port);
friend class DaybreakConnection;
};
}
}
+175
View File
@@ -0,0 +1,175 @@
#pragma once
#include <cereal/cereal.hpp>
#include <cstdint>
#include "endian.h"
namespace EQ
{
namespace Net
{
struct DaybreakHeader
{
static size_t size() { return 2; }
uint8_t zero;
uint8_t opcode;
template <class Archive>
void serialize(Archive & archive)
{
archive(CEREAL_NVP(zero),
CEREAL_NVP(opcode));
}
};
struct DaybreakConnect
{
static size_t size() { return 14; }
uint8_t zero;
uint8_t opcode;
uint32_t protocol_version;
uint32_t connect_code;
uint32_t max_packet_size;
template <class Archive>
void serialize(Archive & archive)
{
archive(CEREAL_NVP(zero),
CEREAL_NVP(opcode),
CEREAL_NVP(protocol_version),
CEREAL_NVP(connect_code),
CEREAL_NVP(max_packet_size));
}
};
struct DaybreakConnectReply
{
static size_t size() { return 17; }
uint8_t zero;
uint8_t opcode;
uint32_t connect_code;
uint32_t encode_key;
uint8_t crc_bytes;
uint8_t encode_pass1;
uint8_t encode_pass2;
uint32_t max_packet_size;
template <class Archive>
void serialize(Archive & archive)
{
archive(CEREAL_NVP(zero),
CEREAL_NVP(opcode),
CEREAL_NVP(connect_code),
CEREAL_NVP(encode_key),
CEREAL_NVP(crc_bytes),
CEREAL_NVP(encode_pass1),
CEREAL_NVP(encode_pass2),
CEREAL_NVP(max_packet_size));
}
};
struct DaybreakDisconnect
{
static size_t size() { return 8; }
uint8_t zero;
uint8_t opcode;
uint32_t connect_code;
uint16_t disconnect_code;
template <class Archive>
void serialize(Archive & archive)
{
archive(CEREAL_NVP(zero),
CEREAL_NVP(opcode),
CEREAL_NVP(connect_code),
CEREAL_NVP(disconnect_code));
}
};
struct DaybreakReliableHeader
{
static size_t size() { return 4; }
uint8_t zero;
uint8_t opcode;
uint16_t sequence;
template <class Archive>
void serialize(Archive & archive)
{
archive(CEREAL_NVP(zero),
CEREAL_NVP(opcode),
CEREAL_NVP(sequence));
}
};
struct DaybreakReliableFragmentHeader
{
static size_t size() { return 4 + DaybreakReliableHeader::size(); }
DaybreakReliableHeader reliable;
uint32_t total_size;
template <class Archive>
void serialize(Archive & archive)
{
archive(CEREAL_NVP(reliable),
CEREAL_NVP(total_size));
}
};
struct DaybreakSessionStatRequestHeader
{
static size_t size() { return 40; }
uint8_t zero;
uint8_t opcode;
uint16_t timestamp;
uint32_t stat_ping;
uint32_t avg_ping;
uint32_t min_ping;
uint32_t max_ping;
uint32_t last_ping;
uint64_t packets_sent;
uint64_t packets_recv;
template <class Archive>
void serialize(Archive & archive)
{
archive(CEREAL_NVP(zero),
CEREAL_NVP(opcode),
CEREAL_NVP(timestamp),
CEREAL_NVP(stat_ping),
CEREAL_NVP(avg_ping),
CEREAL_NVP(min_ping),
CEREAL_NVP(max_ping),
CEREAL_NVP(last_ping),
CEREAL_NVP(packets_sent),
CEREAL_NVP(packets_recv));
}
};
struct DaybreakSessionStatResponseHeader
{
static size_t size() { return 40; }
uint8_t zero;
uint8_t opcode;
uint16_t timestamp;
uint32_t our_timestamp;
uint64_t client_sent;
uint64_t client_recv;
uint64_t server_sent;
uint64_t server_recv;
template <class Archive>
void serialize(Archive & archive)
{
archive(CEREAL_NVP(zero),
CEREAL_NVP(opcode),
CEREAL_NVP(timestamp),
CEREAL_NVP(our_timestamp),
CEREAL_NVP(client_sent),
CEREAL_NVP(client_recv),
CEREAL_NVP(server_sent),
CEREAL_NVP(server_recv));
}
};
}
}
+51
View File
@@ -0,0 +1,51 @@
#pragma once
#include <cstdint>
#include <algorithm>
#include <type_traits>
namespace EQ
{
namespace Net
{
inline bool IsLittleEndian() {
static int32_t v = 1;
return 1 == *(int8_t*)&v;
}
template<typename T>
T ByteSwap(T in) {
static_assert(std::is_integral<T>::value, "Byte swap only works on integer types.");
T ret;
char *first = (char*)&in;
char *last = (char*)&in + sizeof(in);
char *d_first = (char*)&ret;
while (first != last) {
*(d_first++) = *(--last);
}
return ret;
}
template<typename T>
T HostToNetwork(T in) {
if (IsLittleEndian()) {
return ByteSwap(in);
}
else {
return in;
}
}
template<typename T>
T NetworkToHost(T in) {
if (IsLittleEndian()) {
return ByteSwap(in);
}
else {
return in;
}
}
}
}
+115
View File
@@ -0,0 +1,115 @@
#include "eqstream.h"
#include "../eqemu_logsys.h"
EQ::Net::EQStreamManager::EQStreamManager(EQStreamManagerOptions &options) : m_daybreak(options.daybreak_options)
{
m_options = options;
m_daybreak.OnNewConnection(std::bind(&EQStreamManager::DaybreakNewConnection, this, std::placeholders::_1));
m_daybreak.OnConnectionStateChange(std::bind(&EQStreamManager::DaybreakConnectionStateChange, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3));
m_daybreak.OnPacketRecv(std::bind(&EQStreamManager::DaybreakPacketRecv, this, std::placeholders::_1, std::placeholders::_2));
}
EQ::Net::EQStreamManager::~EQStreamManager()
{
}
void EQ::Net::EQStreamManager::DaybreakNewConnection(std::shared_ptr<DaybreakConnection> connection)
{
std::shared_ptr<EQStream> stream(new EQStream(this, connection));
m_streams.insert(std::make_pair(connection, stream));
if (m_on_new_connection) {
m_on_new_connection(stream);
}
}
void EQ::Net::EQStreamManager::DaybreakConnectionStateChange(std::shared_ptr<DaybreakConnection> connection, DbProtocolStatus from, DbProtocolStatus to)
{
auto iter = m_streams.find(connection);
if (iter != m_streams.end()) {
if (m_on_connection_state_change) {
m_on_connection_state_change(iter->second, from, to);
}
if (to == EQ::Net::StatusDisconnected) {
m_streams.erase(iter);
}
}
}
void EQ::Net::EQStreamManager::DaybreakPacketRecv(std::shared_ptr<DaybreakConnection> connection, const Packet &p)
{
auto iter = m_streams.find(connection);
if (iter != m_streams.end()) {
auto patch = iter->second->GetRegisteredPatch();
if (patch == nullptr && m_possible_patches.size() > 0) {
for (auto &pt : m_possible_patches) {
auto match = pt->TryIdentityMatch(p);
if (match == EQ::Patches::IdentityMatchSuccess) {
iter->second->RegisterPatch(pt.get());
patch = pt.get();
Log.OutF(Logs::General, Logs::Debug, "Identified patch with name {0}", pt->GetName());
}
}
}
if (patch) {
EmuOpcode opcode;
EQ::Net::WritablePacket out;
patch->Decode(&p, opcode, out);
if (opcode == OP_Unknown) {
Log.OutF(Logs::General, Logs::Netcode, "Incoming packet was not handled because the opcode was not found.\n{0}", p.ToString());
}
else {
if (m_on_packet_recv) {
m_on_packet_recv(iter->second, opcode, out);
}
}
}
else {
Log.OutF(Logs::General, Logs::Netcode, "Incoming packet was not handled because we don't have a patch set.\n{0}", p.ToString());
}
}
}
EQ::Net::EQStream::EQStream(EQStreamManager *owner, std::shared_ptr<DaybreakConnection> connection)
{
m_owner = owner;
m_connection = connection;
m_patch = nullptr;
}
EQ::Net::EQStream::~EQStream()
{
}
void EQ::Net::EQStream::QueuePacket(EmuOpcode type, const Packet &p)
{
if (m_patch) {
EQ::Net::WritablePacket trans;
m_patch->Encode(m_connection, type, &p);
}
}
void EQ::Net::EQStream::ResetStats()
{
m_connection->ResetStats();
}
void EQ::Net::EQStream::Close()
{
}
void EQ::Net::EQStream::QueuePacket(const EQApplicationPacket *p)
{
EQ::Net::ReadOnlyPacket out(p->pBuffer, p->size);
QueuePacket(p->GetOpcode(), out);
}
void EQ::Net::EQStream::FastQueuePacket(const EQApplicationPacket **p)
{
QueuePacket(*p);
delete *p;
}
+89
View File
@@ -0,0 +1,89 @@
#pragma once
#include "../patch/patch.h"
#include "../eq_packet.h"
#include "daybreak_connection.h"
#include <vector>
namespace EQ
{
namespace Net
{
struct EQStreamManagerOptions
{
EQStreamManagerOptions() {
}
EQStreamManagerOptions(bool encoded, bool compressed) {
if (encoded) {
daybreak_options.encode_passes[0] = EncodeXOR;
if (compressed) {
daybreak_options.encode_passes[1] = EncodeCompression;
}
}
else {
if (compressed) {
daybreak_options.encode_passes[0] = EncodeCompression;
}
}
}
DaybreakConnectionManagerOptions daybreak_options;
};
class EQStream;
class EQStreamManager
{
public:
EQStreamManager(EQStreamManagerOptions &options);
~EQStreamManager();
void OnNewConnection(std::function<void(std::shared_ptr<EQStream>)> func) { m_on_new_connection = func; }
void OnConnectionStateChange(std::function<void(std::shared_ptr<EQStream>, DbProtocolStatus, DbProtocolStatus)> func) { m_on_connection_state_change = func; }
void OnPacketRecv(std::function<void(std::shared_ptr<EQStream>, EmuOpcode, const Packet &)> func) { m_on_packet_recv = func; }
void RegisterPotentialPatch(EQ::Patches::BasePatch *patch) { m_possible_patches.push_back(std::unique_ptr<EQ::Patches::BasePatch>(patch)); }
private:
EQStreamManagerOptions m_options;
DaybreakConnectionManager m_daybreak;
std::function<void(std::shared_ptr<EQStream>)> m_on_new_connection;
std::function<void(std::shared_ptr<EQStream>, DbProtocolStatus, DbProtocolStatus)> m_on_connection_state_change;
std::function<void(std::shared_ptr<EQStream>, EmuOpcode, const Packet &)> m_on_packet_recv;
std::map<std::shared_ptr<DaybreakConnection>, std::shared_ptr<EQStream>> m_streams;
std::vector<std::unique_ptr<EQ::Patches::BasePatch>> m_possible_patches;
void DaybreakNewConnection(std::shared_ptr<DaybreakConnection> connection);
void DaybreakConnectionStateChange(std::shared_ptr<DaybreakConnection> connection, DbProtocolStatus from, DbProtocolStatus to);
void DaybreakPacketRecv(std::shared_ptr<DaybreakConnection> connection, const Packet &p);
friend class EQStream;
};
class EQStream
{
public:
EQStream(EQStreamManager *parent, std::shared_ptr<DaybreakConnection> connection);
~EQStream();
const std::string& RemoteEndpoint() const { return m_connection->RemoteEndpoint(); }
int RemotePort() const { return m_connection->RemotePort(); }
void QueuePacket(EmuOpcode type, const Packet &p);
const DaybreakConnectionStats& GetStats() const { return m_connection->GetStats(); }
void ResetStats();
size_t GetRollingPing() const { return m_connection->GetRollingPing(); }
void Close();
void QueuePacket(const EQApplicationPacket *p);
void FastQueuePacket(const EQApplicationPacket **p);
void RegisterPatch(EQ::Patches::BasePatch *p) { m_patch = p; }
EQ::Patches::BasePatch *GetRegisteredPatch() { return m_patch; }
private:
EQStreamManager *m_owner;
std::shared_ptr<DaybreakConnection> m_connection;
EQ::Patches::BasePatch *m_patch;
friend class EQStreamManager;
};
}
}
+332
View File
@@ -0,0 +1,332 @@
#include "packet.h"
#include "endian.h"
#include <fmt/format.h>
#include <cctype>
void EQ::Net::Packet::PutInt8(size_t offset, int8_t value)
{
if (Length() < offset + 1) {
if (!Resize(offset + 1)) {
throw std::out_of_range("Packet::PutInt8(), could not resize packet and would of written past the end.");
}
}
*(int8_t*)((char*)Data() + offset) = value;
}
void EQ::Net::Packet::PutInt16(size_t offset, int16_t value)
{
if (Length() < offset + 2) {
if (!Resize(offset + 2)) {
throw std::out_of_range("Packet::PutInt16(), could not resize packet and would of written past the end.");
}
}
*(int16_t*)((char*)Data() + offset) = value;
}
void EQ::Net::Packet::PutInt32(size_t offset, int32_t value)
{
if (Length() < offset + 4) {
if (!Resize(offset + 4)) {
throw std::out_of_range("Packet::PutInt32(), could not resize packet and would of written past the end.");
}
}
*(int32_t*)((char*)Data() + offset) = value;
}
void EQ::Net::Packet::PutInt64(size_t offset, int64_t value)
{
if (Length() < offset + 8) {
if (!Resize(offset + 8)) {
throw std::out_of_range("Packet::PutInt64(), could not resize packet and would of written past the end.");
}
}
*(int64_t*)((char*)Data() + offset) = value;
}
void EQ::Net::Packet::PutUInt8(size_t offset, uint8_t value)
{
if (Length() < offset + 1) {
if (!Resize(offset + 1)) {
throw std::out_of_range("Packet::PutUInt8(), could not resize packet and would of written past the end.");
}
}
*(uint8_t*)((char*)Data() + offset) = value;
}
void EQ::Net::Packet::PutUInt16(size_t offset, uint16_t value)
{
if (Length() < offset + 2) {
if (!Resize(offset + 2)) {
throw std::out_of_range("Packet::PutUInt16(), could not resize packet and would of written past the end.");
}
}
*(uint16_t*)((char*)Data() + offset) = value;
}
void EQ::Net::Packet::PutUInt32(size_t offset, uint32_t value)
{
if (Length() < offset + 4) {
if (!Resize(offset + 4)) {
throw std::out_of_range("Packet::PutUInt32(), could not resize packet and would of written past the end.");
}
}
*(uint32_t*)((char*)Data() + offset) = value;
}
void EQ::Net::Packet::PutUInt64(size_t offset, uint64_t value)
{
if (Length() < offset + 8) {
if (!Resize(offset + 8)) {
throw std::out_of_range("Packet::PutUInt64(), could not resize packet and would of written past the end.");
}
}
*(uint64_t*)((char*)Data() + offset) = value;
}
void EQ::Net::Packet::PutFloat(size_t offset, float value)
{
if (Length() < offset + 4) {
if (!Resize(offset + 4)) {
throw std::out_of_range("Packet::PutFloat(), could not resize packet and would of written past the end.");
}
}
*(float*)((char*)Data() + offset) = value;
}
void EQ::Net::Packet::PutDouble(size_t offset, double value)
{
if (Length() < offset + 8) {
if (!Resize(offset + 8)) {
throw std::out_of_range("Packet::PutDouble(), could not resize packet and would of written past the end.");
}
}
*(double*)((char*)Data() + offset) = value;
}
void EQ::Net::Packet::PutString(size_t offset, const std::string &str)
{
if (Length() < offset + str.length()) {
if (!Resize(offset + str.length())) {
throw std::out_of_range("Packet::PutString(), could not resize packet and would of written past the end.");
}
}
memcpy(((char*)Data() + offset), str.c_str(), str.length());
}
void EQ::Net::Packet::PutCString(size_t offset, const char *str)
{
size_t sz = strlen(str);
if (Length() < offset + sz + 1) {
if (!Resize(offset + sz + 1)) {
throw std::out_of_range("Packet::PutCString(), could not resize packet and would of written past the end.");
}
}
memcpy(((char*)Data() + offset), str, sz);
*((char*)Data() + offset + sz) = 0;
}
void EQ::Net::Packet::PutPacket(size_t offset, const Packet &p)
{
if (Length() < offset + p.Length()) {
if (!Resize(offset + p.Length())) {
throw std::out_of_range("Packet::PutPacket(), could not resize packet and would of written past the end.");
}
}
memcpy(((char*)Data() + offset), p.Data(), p.Length());
}
void EQ::Net::Packet::PutData(size_t offset, void *data, size_t length)
{
if (Length() < offset + length) {
if (!Resize(offset + length)) {
throw std::out_of_range("Packet::PutData(), could not resize packet and would of written past the end.");
}
}
memcpy(((char*)Data() + offset), data, length);
}
int8_t EQ::Net::Packet::GetInt8(size_t offset) const
{
if (Length() < offset + 1) {
throw std::out_of_range("Packet read out of range.");
}
return *(int8_t*)((char*)Data() + offset);
}
int16_t EQ::Net::Packet::GetInt16(size_t offset) const
{
if (Length() < offset + 2) {
throw std::out_of_range("Packet read out of range.");
}
return *(int16_t*)((char*)Data() + offset);
}
int32_t EQ::Net::Packet::GetInt32(size_t offset) const
{
if (Length() < offset + 4) {
throw std::out_of_range("Packet read out of range.");
}
return *(int32_t*)((char*)Data() + offset);
}
int64_t EQ::Net::Packet::GetInt64(size_t offset) const
{
if (Length() < offset + 8) {
throw std::out_of_range("Packet read out of range.");
}
return *(int64_t*)((char*)Data() + offset);
}
uint8_t EQ::Net::Packet::GetUInt8(size_t offset) const
{
if (Length() < offset + 1) {
throw std::out_of_range("Packet read out of range.");
}
return *(uint8_t*)((char*)Data() + offset);
}
uint16_t EQ::Net::Packet::GetUInt16(size_t offset) const
{
if (Length() < offset + 2) {
throw std::out_of_range("Packet read out of range.");
}
return *(uint16_t*)((char*)Data() + offset);
}
uint32_t EQ::Net::Packet::GetUInt32(size_t offset) const
{
if (Length() < offset + 4) {
throw std::out_of_range("Packet read out of range.");
}
return *(uint32_t*)((char*)Data() + offset);
}
uint64_t EQ::Net::Packet::GetUInt64(size_t offset) const
{
if (Length() < offset + 8) {
throw std::out_of_range("Packet read out of range.");
}
return *(uint64_t*)((char*)Data() + offset);
}
float EQ::Net::Packet::GetFloat(size_t offset) const
{
if (Length() < offset + 4) {
throw std::out_of_range("Packet read out of range.");
}
return *(float*)((char*)Data() + offset);
}
double EQ::Net::Packet::GetDouble(size_t offset) const
{
if (Length() < offset + 8) {
throw std::out_of_range("Packet read out of range.");
}
return *(double*)((char*)Data() + offset);
}
std::string EQ::Net::Packet::GetString(size_t offset, size_t length) const
{
if (Length() < offset + length) {
throw std::out_of_range("Packet read out of range.");
}
return std::string((char*)Data(), (char*)Data() + length);
}
std::string EQ::Net::Packet::GetCString(size_t offset) const
{
if (Length() < offset + 1) {
throw std::out_of_range("Packet read out of range.");
}
char *str = ((char*)Data() + offset);
return std::string(str);
}
char ToSafePrint(unsigned char in) {
if (std::isprint(in)) {
return in;
}
return '.';
}
std::string EQ::Net::Packet::ToString() const
{
return ToString(16);
}
std::string EQ::Net::Packet::ToString(size_t line_length) const
{
std::string ret;
size_t lines = Length() / line_length;
size_t i;
char *data = (char*)Data();
for (i = 0; i < lines; ++i) {
ret += fmt::format("{:0>5x} |", i * line_length);
std::string hex;
std::string ascii;
for (size_t j = 0; j < line_length; ++j) {
hex += fmt::format(" {:0>2x}", (uint8_t)data[(i * line_length) + j]);
ascii += fmt::format("{}", ToSafePrint(data[(i * line_length) + j]));
}
ret += hex;
ret += " | ";
ret += ascii;
ret += "\n";
}
if (Length() % line_length > 0) {
ret += fmt::format("{:0>5x} |", i * line_length);
size_t non_blank_count = Length() % line_length;
size_t blank_count = line_length - non_blank_count;
std::string hex;
std::string ascii;
for (size_t j = 0; j < non_blank_count; ++j) {
hex += fmt::format(" {:0>2x}", (uint8_t)data[(i * line_length) + j]);
ascii += fmt::format("{}", ToSafePrint(data[(i * line_length) + j]));
}
for (size_t j = 0; j < blank_count; ++j) {
hex += " ";
ascii += " ";
}
ret += hex;
ret += " | ";
ret += ascii;
ret += "\n";
}
return ret;
}
+131
View File
@@ -0,0 +1,131 @@
#pragma once
#include <cstdint>
#include <string>
#include <stdexcept>
#include <cstring>
#include "../util/memory_stream.h"
#include <cereal/cereal.hpp>
#include <cereal/archives/binary.hpp>
namespace EQ {
namespace Net {
class Packet
{
public:
Packet() { }
virtual ~Packet() { }
virtual const void *Data() const = 0;
virtual void *Data() = 0;
virtual size_t Length() const = 0;
virtual size_t Length() = 0;
virtual bool Clear() = 0;
virtual bool Resize(size_t new_size) = 0;
virtual void Reserve(size_t new_size) = 0;
template<typename T>
T GetSerialize(size_t offset) const
{
if (T::size() > (Length() - offset)) {
throw std::out_of_range("Packet::GetSerialize(), packet not large enough to cast to type.");
}
T ret;
Util::MemoryStreamReader reader(((char*)Data() + offset), Length());
cereal::BinaryInputArchive input(reader);
input(ret);
return ret;
}
template<typename T>
void PutSerialize(size_t offset, const T &value) {
std::stringstream buffer(std::ios::in | std::ios::out | std::ios::binary);
cereal::BinaryOutputArchive output(buffer);
output(value);
auto str = buffer.str();
if (Length() < offset + str.length()) {
if (!Resize(offset + str.length())) {
throw std::out_of_range("Packet::PutSerialize(), could not resize packet and would of written past the end.");
}
}
memcpy((char*)Data() + offset, &str[0], str.length());
}
void PutInt8(size_t offset, int8_t value);
void PutInt16(size_t offset, int16_t value);
void PutInt32(size_t offset, int32_t value);
void PutInt64(size_t offset, int64_t value);
void PutUInt8(size_t offset, uint8_t value);
void PutUInt16(size_t offset, uint16_t value);
void PutUInt32(size_t offset, uint32_t value);
void PutUInt64(size_t offset, uint64_t value);
void PutFloat(size_t offset, float value);
void PutDouble(size_t offset, double value);
void PutString(size_t offset, const std::string &str);
void PutCString(size_t offset, const char *str);
void PutPacket(size_t offset, const Packet &p);
void PutData(size_t offset, void *data, size_t length);
int8_t GetInt8(size_t offset) const;
int16_t GetInt16(size_t offset) const;
int32_t GetInt32(size_t offset) const;
int64_t GetInt64(size_t offset) const;
uint8_t GetUInt8(size_t offset) const;
uint16_t GetUInt16(size_t offset) const;
uint32_t GetUInt32(size_t offset) const;
uint64_t GetUInt64(size_t offset) const;
float GetFloat(size_t offset) const;
double GetDouble(size_t offset) const;
std::string GetString(size_t offset, size_t length) const;
std::string GetCString(size_t offset) const;
std::string ToString() const;
std::string ToString(size_t line_length) const;
};
class ReadOnlyPacket : public Packet
{
public:
ReadOnlyPacket(void *data, size_t size) { m_data = data; m_data_length = size; }
virtual ~ReadOnlyPacket() { }
ReadOnlyPacket(const ReadOnlyPacket &o) { m_data = o.m_data; m_data_length = o.m_data_length; }
ReadOnlyPacket& operator=(const ReadOnlyPacket &o) { m_data = o.m_data; m_data_length = o.m_data_length; return *this; }
ReadOnlyPacket(ReadOnlyPacket &&o) { m_data = o.m_data; m_data_length = o.m_data_length; }
virtual const void *Data() const { return m_data; }
virtual void *Data() { return m_data; }
virtual size_t Length() const { return m_data_length; }
virtual size_t Length() { return m_data_length; }
virtual bool Clear() { return false; }
virtual bool Resize(size_t new_size) { return false; }
virtual void Reserve(size_t new_size) { }
protected:
void *m_data;
size_t m_data_length;
};
class WritablePacket : public Packet
{
public:
WritablePacket() { }
virtual ~WritablePacket() { }
WritablePacket(WritablePacket &&o) { m_data = std::move(o.m_data); }
WritablePacket(const WritablePacket &o) { m_data = o.m_data; }
WritablePacket& operator=(const WritablePacket &o) { m_data = o.m_data; return *this; }
virtual const void *Data() const { return &m_data[0]; }
virtual void *Data() { return &m_data[0]; }
virtual size_t Length() const { return m_data.size(); }
virtual size_t Length() { return m_data.size(); }
virtual bool Clear() { m_data.clear(); return true; }
virtual bool Resize(size_t new_size) { m_data.resize(new_size); return true; }
virtual void Reserve(size_t new_size) { m_data.reserve(new_size); }
protected:
std::vector<char> m_data;
};
}
}
+2 -2
View File
@@ -173,7 +173,7 @@ IN(OP_TradeAcceptClick, TradeAccept_Struct);
IN(OP_BoardBoat, EntityId_Struct); //not really the struct, just 4 bytes
INz(OP_LeaveBoat); //?
IN(OP_RandomReq, RandomReq_Struct);
IN(OP_Buff, SpellBuffFade_Struct);
IN(OP_Buff, SpellBuffPacket_Struct);
IN(OP_GMHideMe, SpawnAppearance_Struct);
IN(OP_GMNameChange, GMName_Struct);
IN(OP_GMKill, GMKill_Struct);
@@ -415,7 +415,7 @@ OUTv(OP_SendAATable, SendAA_Struct);
OUT(OP_AAAction, UseAA_Struct);
OUT(OP_Bazaar, BazaarReturnDone_Struct);
//alt:OUT(OP_Bazaar, BazaarWelcome_Struct);
OUT(OP_Buff, SpellBuffFade_Struct);
OUT(OP_Buff, SpellBuffPacket_Struct);
OUT(OP_ClickObject, ClickObject_Struct);
OUT(OP_ClientUpdate, PlayerPositionUpdateServer_Struct);
OUT(OP_SpawnPositionUpdate, SpawnPositionUpdate_Struct);
+17
View File
@@ -0,0 +1,17 @@
#include "chat.h"
EQ::Patches::ChatPatch::ChatPatch()
{
m_opcode_manager.reset(new RegularOpcodeManager());
if (!m_opcode_manager->LoadOpcodes("mail_opcodes.conf")) {
m_opcode_manager.release();
}
m_signature.match_message_opcode = 0x0;
m_signature.match_message_size = 0;
m_message_size = 1;
}
EQ::Patches::ChatPatch::~ChatPatch()
{
}
+15
View File
@@ -0,0 +1,15 @@
#include "../patch/patch.h"
namespace EQ
{
namespace Patches
{
class ChatPatch : public BasePatch
{
public:
ChatPatch();
virtual ~ChatPatch();
virtual std::string GetName() const { return "Chat"; }
};
}
}
+17
View File
@@ -0,0 +1,17 @@
#include "login_sod.h"
EQ::Patches::LoginSoDPatch::LoginSoDPatch()
{
m_opcode_manager.reset(new RegularOpcodeManager());
if (!m_opcode_manager->LoadOpcodes("login_opcodes_sod.conf")) {
m_opcode_manager.release();
}
m_signature.match_message_opcode = 0x01;
m_signature.match_message_size = 0;
m_message_size = 2;
}
EQ::Patches::LoginSoDPatch::~LoginSoDPatch()
{
}
+15
View File
@@ -0,0 +1,15 @@
#include "../patch/patch.h"
namespace EQ
{
namespace Patches
{
class LoginSoDPatch : public BasePatch
{
public:
LoginSoDPatch();
virtual ~LoginSoDPatch();
virtual std::string GetName() const { return "Login SoD+"; }
};
}
}
+17
View File
@@ -0,0 +1,17 @@
#include "login_titanium.h"
EQ::Patches::LoginTitaniumPatch::LoginTitaniumPatch()
{
m_opcode_manager.reset(new RegularOpcodeManager());
if (!m_opcode_manager->LoadOpcodes("login_opcodes.conf")) {
m_opcode_manager.release();
}
m_signature.match_message_opcode = 0x01;
m_signature.match_message_size = 0;
m_message_size = 2;
}
EQ::Patches::LoginTitaniumPatch::~LoginTitaniumPatch()
{
}
+15
View File
@@ -0,0 +1,15 @@
#include "../patch/patch.h"
namespace EQ
{
namespace Patches
{
class LoginTitaniumPatch : public BasePatch
{
public:
LoginTitaniumPatch();
virtual ~LoginTitaniumPatch();
virtual std::string GetName() const { return "Login Titanium"; }
};
}
}
+107
View File
@@ -0,0 +1,107 @@
#include "patch.h"
#include "../eqemu_logsys.h"
EQ::Patches::IdentityMatchStatus EQ::Patches::BasePatch::TryIdentityMatch(const EQ::Net::Packet &p) const
{
if (p.Length() < m_message_size) {
return IdentityMatchFailure;
}
int raw_opcode = 0;
switch (m_message_size) {
case 1:
raw_opcode = *(uint8_t*)p.Data();
break;
case 2:
raw_opcode = *(uint16_t*)p.Data();
break;
default:
return IdentityMatchFailure;
}
if (m_signature.match_message_opcode != 0 && m_signature.match_message_opcode != raw_opcode) {
return IdentityMatchFailure;
}
if (m_signature.match_message_size > 0 && m_signature.match_message_size != p.Length() - m_message_size) {
return IdentityMatchFailure;
}
return IdentityMatchSuccess;
}
void EQ::Patches::BasePatch::Decode(const EQ::Net::Packet *in, EmuOpcode &opcode, EQ::Net::WritablePacket &out)
{
int raw_opcode = 0;
switch (m_message_size) {
case 1:
raw_opcode = *(uint8_t*)in->Data();
break;
case 2:
raw_opcode = *(uint16_t*)in->Data();
break;
default:
opcode = OP_Unknown;
return;
}
opcode = m_opcode_manager->EQToEmu(raw_opcode);
if (opcode == OP_Unknown) {
out.PutData(0, (uint8_t*)in->Data() + m_message_size, in->Length() - m_message_size);
return;
}
auto decode_iter = m_decode.find(opcode);
if (decode_iter != m_decode.end()) {
EQ::Net::ReadOnlyPacket p((uint8_t*)in->Data() + m_message_size, in->Length() - m_message_size);
decode_iter->second(&p, opcode, out);
}
else {
out.PutData(0, (uint8_t*)in->Data() + m_message_size, in->Length() - m_message_size);
}
}
void EQ::Patches::BasePatch::Encode(std::shared_ptr<EQ::Net::DaybreakConnection> connection, EmuOpcode opcode, const EQ::Net::Packet *in)
{
auto encode_iter = m_encode.find(opcode);
if (encode_iter != m_encode.end()) {
encode_iter->second(connection, opcode, in);
}
else {
SendPacket(connection, opcode, in);
}
}
void EQ::Patches::BasePatch::RegisterDecode(int protocol_number, DecodeStructFunction f)
{
m_decode.insert(std::make_pair(protocol_number, f));
}
void EQ::Patches::BasePatch::RegisterEncode(EmuOpcode opcode, EncodeStructFunction f)
{
m_encode.insert(std::make_pair(opcode, f));
}
void EQ::Patches::BasePatch::SendPacket(std::shared_ptr<EQ::Net::DaybreakConnection> connection, EmuOpcode opcode, const EQ::Net::Packet *p)
{
if (!m_opcode_manager) {
return;
}
auto raw_opcode = m_opcode_manager->EmuToEQ(opcode);
EQ::Net::WritablePacket out;
switch (m_message_size) {
case 1:
out.PutUInt8(0, (uint8_t)raw_opcode);
out.PutPacket(1, *p);
break;
case 2:
out.PutUInt16(0, raw_opcode);
out.PutPacket(2, *p);
break;
default:
return;
}
connection->QueuePacket(out);
}
+53
View File
@@ -0,0 +1,53 @@
#pragma once
#include "../opcodemgr.h"
#include "../net/packet.h"
#include "../net/daybreak_connection.h"
#include <functional>
#include <memory>
#include <map>
namespace EQ
{
namespace Patches
{
enum IdentityMatchStatus
{
IdentityMatchFailure,
IdentityMatchSuccess
};
struct Signature
{
int match_message_opcode;
size_t match_message_size;
};
class BasePatch
{
public:
typedef std::function<void(const EQ::Net::Packet*, EmuOpcode, EQ::Net::WritablePacket&)> DecodeStructFunction;
typedef std::function<void(std::shared_ptr<EQ::Net::DaybreakConnection>, EmuOpcode, const EQ::Net::Packet*)> EncodeStructFunction;
BasePatch() { }
virtual ~BasePatch() { }
virtual std::string GetName() const = 0;
IdentityMatchStatus TryIdentityMatch(const EQ::Net::Packet &p) const;
void Decode(const EQ::Net::Packet *in, EmuOpcode& opcode, EQ::Net::WritablePacket& out);
void Encode(std::shared_ptr<EQ::Net::DaybreakConnection> connection, EmuOpcode opcode, const EQ::Net::Packet *in);
void RegisterDecode(int protocol_number, DecodeStructFunction f);
void RegisterEncode(EmuOpcode opcode, EncodeStructFunction f);
protected:
void SendPacket(std::shared_ptr<EQ::Net::DaybreakConnection> connection, EmuOpcode opcode, const EQ::Net::Packet *p);
std::unique_ptr<OpcodeManager> m_opcode_manager;
std::map<int, DecodeStructFunction> m_decode;
std::map<EmuOpcode, EncodeStructFunction> m_encode;
Signature m_signature;
int m_message_size;
};
}
}
View File
View File
View File
File diff suppressed because it is too large Load Diff
+166 -80
View File
@@ -63,6 +63,9 @@ namespace RoF
// client to server text link converter
static inline void RoFToServerTextLink(std::string& serverTextLink, const std::string& rofTextLink);
static inline CastingSlot ServerToRoFCastingSlot(EQEmu::CastingSlot slot);
static inline EQEmu::CastingSlot RoFToServerCastingSlot(CastingSlot slot);
void Register(EQStreamIdentifier &into)
{
//create our opcode manager if we havent already
@@ -405,22 +408,31 @@ namespace RoF
ENCODE(OP_Buff)
{
ENCODE_LENGTH_EXACT(SpellBuffFade_Struct);
SETUP_DIRECT_ENCODE(SpellBuffFade_Struct, structs::SpellBuffFade_Struct_Live);
ENCODE_LENGTH_EXACT(SpellBuffPacket_Struct);
SETUP_DIRECT_ENCODE(SpellBuffPacket_Struct, structs::SpellBuffPacket_Struct);
OUT(entityid);
eq->unknown004 = 2;
//eq->level = 80;
//eq->effect = 0;
OUT(level);
OUT(effect);
eq->unknown007 = 0;
eq->unknown008 = 1.0f;
OUT(spellid);
OUT(duration);
eq->playerId = 0x7cde;
OUT(slotid);
OUT(num_hits);
OUT(buff.effect_type);
OUT(buff.level);
// just so we're 100% sure we get a 1.0f ...
eq->buff.bard_modifier = emu->buff.bard_modifier == 10 ? 1.0f : emu->buff.bard_modifier / 10.0f;
OUT(buff.spellid);
OUT(buff.duration);
OUT(buff.player_id);
OUT(buff.num_hits);
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 = buffslot;
if (emu->bufffade == 1)
eq->bufffade = 1;
else
@@ -432,10 +444,10 @@ namespace RoF
{
outapp = new EQApplicationPacket(OP_BuffCreate, 29);
outapp->WriteUInt32(emu->entityid);
outapp->WriteUInt32(0x0271); // Unk
outapp->WriteUInt32(0); // tic timer
outapp->WriteUInt8(0); // Type of OP_BuffCreate packet ?
outapp->WriteUInt16(1); // 1 buff in this packet
outapp->WriteUInt32(emu->slotid);
outapp->WriteUInt32(buffslot);
outapp->WriteUInt32(0xffffffff); // SpellID (0xffff to remove)
outapp->WriteUInt32(0); // Duration
outapp->WriteUInt32(0); // ?
@@ -465,10 +477,11 @@ namespace RoF
for (uint16 i = 0; i < emu->count; ++i)
{
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;
if (emu->type == 0) { // only correct for self packets
if (emu->entries[i].buff_slot >= 25)
buffslot += 17;
if (buffslot == 54)
buffslot = 62;
}
__packet->WriteUInt32(buffslot);
@@ -498,10 +511,7 @@ namespace RoF
ENCODE_LENGTH_EXACT(CastSpell_Struct);
SETUP_DIRECT_ENCODE(CastSpell_Struct, structs::CastSpell_Struct);
if (emu->slot == 10)
eq->slot = 13;
else
OUT(slot);
eq->slot = static_cast<uint32>(ServerToRoFCastingSlot(static_cast<EQEmu::CastingSlot>(emu->slot)));
OUT(spell_id);
eq->inventory_slot = ServerToRoFSlot(emu->inventoryslot);
@@ -977,8 +987,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, 0); // X tilt
VARSTRUCT_ENCODE_TYPE(float, OutBuffer, 0); // Y tilt
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, 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);
@@ -1614,7 +1624,8 @@ namespace RoF
OUT(new_mana);
OUT(stamina);
OUT(spell_id);
eq->unknown16 = -1; // Self Interrupt/Success = -1, Fizzle = 1, Other Interrupt = 2?
OUT(keepcasting);
eq->slot = -1; // this is spell gem slot. It's -1 in normal operation
FINISH_ENCODE();
}
@@ -2003,18 +2014,18 @@ namespace RoF
__packet->WriteUInt8(1); // 1 indicates all buffs on the pet (0 to add or remove a single buff)
__packet->WriteUInt16(emu->buffcount);
for (uint16 i = 0; i < BUFF_COUNT; ++i)
for (uint16 i = 0; i < PET_BUFF_COUNT; ++i)
{
if (emu->spellid[i])
{
__packet->WriteUInt32(i);
__packet->WriteUInt32(emu->spellid[i]);
__packet->WriteUInt32(emu->ticsremaining[i]);
__packet->WriteUInt32(0); // Unknown
__packet->WriteUInt32(0); // numhits
__packet->WriteString("");
}
}
__packet->WriteUInt8(0); // Unknown
__packet->WriteUInt8(0); // some sort of type
FINISH_ENCODE();
}
@@ -2068,9 +2079,9 @@ namespace RoF
outapp->WriteUInt32(22); // Equipment count
for (int r = 0; r < 9; r++)
for (int r = EQEmu::textures::TextureBegin; r < EQEmu::textures::TextureCount; r++)
{
outapp->WriteUInt32(emu->item_material[r]);
outapp->WriteUInt32(emu->item_material.Slot[r].Material);
outapp->WriteUInt32(0);
outapp->WriteUInt32(0);
outapp->WriteUInt32(0);
@@ -2088,9 +2099,9 @@ namespace RoF
outapp->WriteUInt32(0);
}
outapp->WriteUInt32(9); // Equipment2 count
outapp->WriteUInt32(EQEmu::textures::TextureCount); // Equipment2 count
for (int r = 0; r < 9; r++)
for (int r = EQEmu::textures::TextureBegin; r < EQEmu::textures::TextureCount; r++)
{
outapp->WriteUInt32(0);
outapp->WriteUInt32(0);
@@ -2099,21 +2110,21 @@ namespace RoF
outapp->WriteUInt32(0);
}
outapp->WriteUInt32(9); // Tint Count
outapp->WriteUInt32(EQEmu::textures::TextureCount); // Tint Count
for (int r = 0; r < 7; r++)
{
outapp->WriteUInt32(emu->item_tint[r].Color);
outapp->WriteUInt32(emu->item_tint.Slot[r].Color);
}
// Write zeroes for extra two tint values
outapp->WriteUInt32(0);
outapp->WriteUInt32(0);
outapp->WriteUInt32(9); // Tint2 Count
outapp->WriteUInt32(EQEmu::textures::TextureCount); // Tint2 Count
for (int r = 0; r < 7; r++)
{
outapp->WriteUInt32(emu->item_tint[r].Color);
outapp->WriteUInt32(emu->item_tint.Slot[r].Color);
}
// Write zeroes for extra two tint values
outapp->WriteUInt32(0);
@@ -2250,22 +2261,23 @@ namespace RoF
outapp->WriteUInt32(structs::MAX_PP_MEMSPELL); // Memorised spell slots
for (uint32 r = 0; r < MAX_PP_MEMSPELL; r++)
for (uint32 r = 0; r < MAX_PP_MEMSPELL; r++) // first 12
{
outapp->WriteUInt32(emu->mem_spells[r]);
}
// zeroes for the rest of the slots
// zeroes for the rest of the slots -- the other 4 which don't work at all!
for (uint32 r = 0; r < structs::MAX_PP_MEMSPELL - MAX_PP_MEMSPELL; r++)
{
outapp->WriteUInt32(0xFFFFFFFFU);
}
outapp->WriteUInt32(13); // Unknown count
outapp->WriteUInt32(13); // gem refresh count
for (uint32 r = 0; r < 13; r++)
for (uint32 r = 0; r < MAX_PP_MEMSPELL; r++)
{
outapp->WriteUInt32(0); // Unknown
outapp->WriteUInt32(emu->spellSlotRefresh[r]); // spell gem refresh
}
outapp->WriteUInt32(0); // also refresh -- historically HT/LoH :P
outapp->WriteUInt8(0); // Unknown
@@ -2274,31 +2286,32 @@ namespace RoF
for (uint32 r = 0; r < BUFF_COUNT; r++)
{
float instrument_mod = 0.0f;
uint8 slotid = emu->buffs[r].slotid;
uint8 effect_type = emu->buffs[r].effect_type;
uint32 player_id = emu->buffs[r].player_id;;
if (emu->buffs[r].spellid != 0xFFFF && emu->buffs[r].spellid != 0)
{
instrument_mod = 1.0f + (emu->buffs[r].bard_modifier - 10) / 10.0f;
slotid = 2;
effect_type = 2;
player_id = 0x000717fd;
}
else
{
slotid = 0;
effect_type = 0;
}
outapp->WriteUInt8(0); // Had this as slot, but always appears to be 0 on live.
// this is different than the client struct for some reason :P
// missing a few things, shuffled around
outapp->WriteUInt8(0); // this is an unknown
outapp->WriteFloat(instrument_mod);
outapp->WriteUInt32(player_id);
outapp->WriteUInt8(0);
outapp->WriteUInt32(emu->buffs[r].counters);
//outapp->WriteUInt8(emu->buffs[r].bard_modifier);
outapp->WriteUInt32(emu->buffs[r].duration);
outapp->WriteUInt8(emu->buffs[r].level);
outapp->WriteUInt32(emu->buffs[r].spellid);
outapp->WriteUInt32(slotid); // Only ever seen 2
outapp->WriteUInt8(effect_type); // Only ever seen 2
outapp->WriteUInt32(emu->buffs[r].num_hits);
outapp->WriteUInt32(0);
outapp->WriteUInt8(0);
outapp->WriteUInt32(emu->buffs[r].counters); // Appears twice ?
for (uint32 j = 0; j < 44; ++j)
@@ -3046,13 +3059,13 @@ namespace RoF
eq_cse->Gender = emu_cse->Gender;
eq_cse->Face = emu_cse->Face;
for (int equip_index = 0; equip_index < EQEmu::legacy::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].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.Color = emu_cse->Equip[equip_index].Color.Color;
eq_cse->Equip[equip_index].Color = emu_cse->Equip[equip_index].Color;
}
eq_cse->Unknown15 = emu_cse->Unknown15;
@@ -4083,24 +4096,24 @@ namespace RoF
if ((emu->NPC == 0) || (emu->race <= 12) || (emu->race == 128) || (emu->race == 130) || (emu->race == 330) || (emu->race == 522))
{
for (k = 0; k < 9; ++k)
for (k = EQEmu::textures::TextureBegin; k < EQEmu::textures::TextureCount; ++k)
{
{
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, emu->colors[k].Color);
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, emu->equipment_tint.Slot[k].Color);
}
}
structs::EquipStruct *Equipment = (structs::EquipStruct *)Buffer;
structs::Texture_Struct *Equipment = (structs::Texture_Struct *)Buffer;
for (k = 0; k < 9; k++) {
Equipment[k].Material = emu->equipment[k].Material;
Equipment[k].Unknown1 = emu->equipment[k].Unknown1;
Equipment[k].EliteMaterial = emu->equipment[k].EliteMaterial;
Equipment[k].HeroForgeModel = emu->equipment[k].HeroForgeModel;
Equipment[k].Material2 = emu->equipment[k].Material2;
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].EliteMaterial;
Equipment[k].HeroForgeModel = emu->equipment.Slot[k].HeroForgeModel;
Equipment[k].Material2 = emu->equipment.Slot[k].Material2;
}
Buffer += (sizeof(structs::EquipStruct) * 9);
Buffer += (sizeof(structs::Texture_Struct) * EQEmu::textures::TextureCount);
}
else
{
@@ -4110,13 +4123,13 @@ namespace RoF
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0);
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0);
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, emu->equipment[EQEmu::legacy::MaterialPrimary].Material);
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, emu->equipment.Primary.Material);
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0);
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0);
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0);
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0);
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, emu->equipment[EQEmu::legacy::MaterialSecondary].Material);
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, emu->equipment.Secondary.Material);
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0);
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0);
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0);
@@ -4290,15 +4303,15 @@ namespace RoF
DECODE(OP_Buff)
{
DECODE_LENGTH_EXACT(structs::SpellBuffFade_Struct_Live);
SETUP_DIRECT_DECODE(SpellBuffFade_Struct, structs::SpellBuffFade_Struct_Live);
DECODE_LENGTH_EXACT(structs::SpellBuffPacket_Struct);
SETUP_DIRECT_DECODE(SpellBuffPacket_Struct, structs::SpellBuffPacket_Struct);
IN(entityid);
//IN(slot);
IN(level);
IN(effect);
IN(spellid);
IN(duration);
IN(buff.effect_type);
IN(buff.level);
IN(buff.unknown003);
IN(buff.spellid);
IN(buff.duration);
IN(slotid);
IN(bufffade);
@@ -4324,10 +4337,7 @@ namespace RoF
DECODE_LENGTH_EXACT(structs::CastSpell_Struct);
SETUP_DIRECT_DECODE(CastSpell_Struct, structs::CastSpell_Struct);
if (eq->slot == 13)
emu->slot = 10;
else
IN(slot);
emu->slot = static_cast<uint32>(RoFToServerCastingSlot(static_cast<CastingSlot>(eq->slot)));
IN(spell_id);
emu->inventoryslot = RoFToServerSlot(eq->inventory_slot);
@@ -5201,7 +5211,7 @@ namespace RoF
void SerializeItem(EQEmu::OutBuffer& ob, const ItemInst *inst, int16 slot_id_in, uint8 depth)
{
const EQEmu::Item_Struct *item = inst->GetUnscaledItem();
const EQEmu::ItemBase *item = inst->GetUnscaledItem();
RoF::structs::ItemSerializationHeader hdr;
@@ -5209,7 +5219,7 @@ namespace RoF
snprintf(hdr.unknown000, sizeof(hdr.unknown000), "%016d", item->ID);
hdr.stacksize = (inst->IsStackable() ? ((inst->GetCharges() > 254) ? 0xFFFFFFFF : inst->GetCharges()) : 1);
hdr.stacksize = (inst->IsStackable() ? ((inst->GetCharges() > 1000) ? 0xFFFFFFFF : inst->GetCharges()) : 1);
hdr.unknown004 = 0;
structs::InventorySlot_Struct slot_id = ServerToRoFSlot(slot_id_in);
@@ -5641,11 +5651,11 @@ namespace RoF
{
structs::InventorySlot_Struct RoFSlot;
RoFSlot.Type = INVALID_INDEX;
RoFSlot.Unknown02 = NOT_USED;
RoFSlot.Unknown02 = 0;
RoFSlot.Slot = INVALID_INDEX;
RoFSlot.SubIndex = INVALID_INDEX;
RoFSlot.AugIndex = INVALID_INDEX;
RoFSlot.Unknown01 = NOT_USED;
RoFSlot.Unknown01 = 0;
uint32 TempSlot = 0;
@@ -5746,7 +5756,7 @@ namespace RoF
RoFSlot.Slot = INVALID_INDEX;
RoFSlot.SubIndex = INVALID_INDEX;
RoFSlot.AugIndex = INVALID_INDEX;
RoFSlot.Unknown01 = NOT_USED;
RoFSlot.Unknown01 = 0;
uint32 TempSlot = 0;
@@ -5999,4 +6009,80 @@ namespace RoF
}
}
static inline CastingSlot ServerToRoFCastingSlot(EQEmu::CastingSlot slot)
{
switch (slot) {
case EQEmu::CastingSlot::Gem1:
return CastingSlot::Gem1;
case EQEmu::CastingSlot::Gem2:
return CastingSlot::Gem2;
case EQEmu::CastingSlot::Gem3:
return CastingSlot::Gem3;
case EQEmu::CastingSlot::Gem4:
return CastingSlot::Gem4;
case EQEmu::CastingSlot::Gem5:
return CastingSlot::Gem5;
case EQEmu::CastingSlot::Gem6:
return CastingSlot::Gem6;
case EQEmu::CastingSlot::Gem7:
return CastingSlot::Gem7;
case EQEmu::CastingSlot::Gem8:
return CastingSlot::Gem8;
case EQEmu::CastingSlot::Gem9:
return CastingSlot::Gem9;
case EQEmu::CastingSlot::Gem10:
return CastingSlot::Gem10;
case EQEmu::CastingSlot::Gem11:
return CastingSlot::Gem11;
case EQEmu::CastingSlot::Gem12:
return CastingSlot::Gem12;
case EQEmu::CastingSlot::Item:
case EQEmu::CastingSlot::PotionBelt:
return CastingSlot::Item;
case EQEmu::CastingSlot::Discipline:
return CastingSlot::Discipline;
case EQEmu::CastingSlot::AltAbility:
return CastingSlot::AltAbility;
default: // we shouldn't have any issues with other slots ... just return something
return CastingSlot::Discipline;
}
}
static inline EQEmu::CastingSlot RoFToServerCastingSlot(CastingSlot slot)
{
switch (slot) {
case CastingSlot::Gem1:
return EQEmu::CastingSlot::Gem1;
case CastingSlot::Gem2:
return EQEmu::CastingSlot::Gem2;
case CastingSlot::Gem3:
return EQEmu::CastingSlot::Gem3;
case CastingSlot::Gem4:
return EQEmu::CastingSlot::Gem4;
case CastingSlot::Gem5:
return EQEmu::CastingSlot::Gem5;
case CastingSlot::Gem6:
return EQEmu::CastingSlot::Gem6;
case CastingSlot::Gem7:
return EQEmu::CastingSlot::Gem7;
case CastingSlot::Gem8:
return EQEmu::CastingSlot::Gem8;
case CastingSlot::Gem9:
return EQEmu::CastingSlot::Gem9;
case CastingSlot::Gem10:
return EQEmu::CastingSlot::Gem10;
case CastingSlot::Gem11:
return EQEmu::CastingSlot::Gem11;
case CastingSlot::Gem12:
return EQEmu::CastingSlot::Gem12;
case CastingSlot::Discipline:
return EQEmu::CastingSlot::Discipline;
case CastingSlot::Item:
return EQEmu::CastingSlot::Item;
case CastingSlot::AltAbility:
return EQEmu::CastingSlot::AltAbility;
default: // we shouldn't have any issues with other slots ... just return something
return EQEmu::CastingSlot::Discipline;
}
}
} /*RoF*/
+18
View File
@@ -50,6 +50,24 @@ namespace RoF
#include "rof_ops.h"
};
enum class CastingSlot : uint32 {
Gem1 = 0,
Gem2 = 1,
Gem3 = 2,
Gem4 = 3,
Gem5 = 4,
Gem6 = 5,
Gem7 = 6,
Gem8 = 7,
Gem9 = 8,
Gem10 = 9,
Gem11 = 10,
Gem12 = 11,
Item = 12,
Discipline = 13,
AltAbility = 0xFF
};
}; /*RoF*/
#endif /*COMMON_ROF_H*/
+186 -85
View File
@@ -63,6 +63,9 @@ namespace RoF2
// client to server text link converter
static inline void RoF2ToServerTextLink(std::string& serverTextLink, const std::string& rof2TextLink);
static inline CastingSlot ServerToRoF2CastingSlot(EQEmu::CastingSlot slot);
static inline EQEmu::CastingSlot RoF2ToServerCastingSlot(CastingSlot slot);
void Register(EQStreamIdentifier &into)
{
//create our opcode manager if we havent already
@@ -474,22 +477,34 @@ namespace RoF2
ENCODE(OP_Buff)
{
ENCODE_LENGTH_EXACT(SpellBuffFade_Struct);
SETUP_DIRECT_ENCODE(SpellBuffFade_Struct, structs::SpellBuffFade_Struct_Live);
ENCODE_LENGTH_EXACT(SpellBuffPacket_Struct);
SETUP_DIRECT_ENCODE(SpellBuffPacket_Struct, structs::SpellBuffPacket_Struct);
OUT(entityid);
eq->unknown004 = 2;
//eq->level = 80;
//eq->effect = 0;
OUT(level);
OUT(effect);
eq->unknown007 = 0;
eq->unknown008 = 1.0f;
OUT(spellid);
OUT(duration);
eq->playerId = 0x7cde;
OUT(slotid);
OUT(num_hits);
OUT(buff.effect_type);
OUT(buff.level);
// just so we're 100% sure we get a 1.0f ...
eq->buff.bard_modifier = emu->buff.bard_modifier == 10 ? 1.0f : emu->buff.bard_modifier / 10.0f;
OUT(buff.spellid);
OUT(buff.duration);
OUT(buff.player_id);
OUT(buff.num_hits);
OUT(buff.y);
OUT(buff.x);
OUT(buff.z);
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;
else
@@ -501,10 +516,10 @@ namespace RoF2
{
outapp = new EQApplicationPacket(OP_BuffCreate, 29);
outapp->WriteUInt32(emu->entityid);
outapp->WriteUInt32(0x0271); // Unk
outapp->WriteUInt32(0); // tic timer
outapp->WriteUInt8(0); // Type of OP_BuffCreate packet ?
outapp->WriteUInt16(1); // 1 buff in this packet
outapp->WriteUInt32(emu->slotid);
outapp->WriteUInt32(buffslot);
outapp->WriteUInt32(0xffffffff); // SpellID (0xffff to remove)
outapp->WriteUInt32(0); // Duration
outapp->WriteUInt32(0); // ?
@@ -534,16 +549,15 @@ namespace RoF2
for (uint16 i = 0; i < emu->count; ++i)
{
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;
if (emu->type == 0) { // only correct for self packets
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;
}
// 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);
@@ -572,10 +586,7 @@ namespace RoF2
ENCODE_LENGTH_EXACT(CastSpell_Struct);
SETUP_DIRECT_ENCODE(CastSpell_Struct, structs::CastSpell_Struct);
if (emu->slot == 10)
eq->slot = 13;
else
OUT(slot);
eq->slot = static_cast<uint32>(ServerToRoF2CastingSlot(static_cast<EQEmu::CastingSlot>(emu->slot)));
OUT(spell_id);
eq->inventory_slot = ServerToRoF2Slot(emu->inventoryslot);
@@ -1051,8 +1062,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, 0); // X tilt
VARSTRUCT_ENCODE_TYPE(float, OutBuffer, 0); // Y tilt
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, 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);
@@ -1689,7 +1700,8 @@ namespace RoF2
OUT(new_mana);
OUT(stamina);
OUT(spell_id);
eq->unknown16 = -1; // Self Interrupt/Success = -1, Fizzle = 1, Other Interrupt = 2?
OUT(keepcasting);
eq->slot = -1; // this is spell gem slot. It's -1 in normal operation
FINISH_ENCODE();
}
@@ -2087,18 +2099,18 @@ namespace RoF2
__packet->WriteUInt8(1); // 1 indicates all buffs on the pet (0 to add or remove a single buff)
__packet->WriteUInt16(emu->buffcount);
for (uint16 i = 0; i < BUFF_COUNT; ++i)
for (uint16 i = 0; i < PET_BUFF_COUNT; ++i)
{
if (emu->spellid[i])
{
__packet->WriteUInt32(i);
__packet->WriteUInt32(emu->spellid[i]);
__packet->WriteUInt32(emu->ticsremaining[i]);
__packet->WriteUInt32(0); // Unknown
__packet->WriteUInt32(0); // num hits
__packet->WriteString("");
}
}
__packet->WriteUInt8(0); // Unknown
__packet->WriteUInt8(0); // some sort of type
FINISH_ENCODE();
}
@@ -2152,9 +2164,9 @@ namespace RoF2
outapp->WriteUInt32(22); // Equipment count
for (int r = 0; r < 9; r++)
for (int r = EQEmu::textures::TextureBegin; r < EQEmu::textures::TextureCount; r++)
{
outapp->WriteUInt32(emu->item_material[r]);
outapp->WriteUInt32(emu->item_material.Slot[r].Material);
outapp->WriteUInt32(0);
outapp->WriteUInt32(0);
outapp->WriteUInt32(0);
@@ -2172,9 +2184,9 @@ namespace RoF2
outapp->WriteUInt32(0);
}
outapp->WriteUInt32(9); // Equipment2 count
outapp->WriteUInt32(EQEmu::textures::TextureCount); // Equipment2 count
for (int r = 0; r < 9; r++)
for (int r = EQEmu::textures::TextureBegin; r < EQEmu::textures::TextureCount; r++)
{
outapp->WriteUInt32(0);
outapp->WriteUInt32(0);
@@ -2183,21 +2195,21 @@ namespace RoF2
outapp->WriteUInt32(0);
}
outapp->WriteUInt32(9); // Tint Count
outapp->WriteUInt32(EQEmu::textures::TextureCount); // Tint Count
for (int r = 0; r < 7; r++)
{
outapp->WriteUInt32(emu->item_tint[r].Color);
outapp->WriteUInt32(emu->item_tint.Slot[r].Color);
}
// Write zeroes for extra two tint values
outapp->WriteUInt32(0);
outapp->WriteUInt32(0);
outapp->WriteUInt32(9); // Tint2 Count
outapp->WriteUInt32(EQEmu::textures::TextureCount); // Tint2 Count
for (int r = 0; r < 7; r++)
{
outapp->WriteUInt32(emu->item_tint[r].Color);
outapp->WriteUInt32(emu->item_tint.Slot[r].Color);
}
// Write zeroes for extra two tint values
outapp->WriteUInt32(0);
@@ -2334,22 +2346,23 @@ namespace RoF2
outapp->WriteUInt32(structs::MAX_PP_MEMSPELL); // Memorised spell slots
for (uint32 r = 0; r < MAX_PP_MEMSPELL; r++)
for (uint32 r = 0; r < MAX_PP_MEMSPELL; r++) // write first 12
{
outapp->WriteUInt32(emu->mem_spells[r]);
}
// zeroes for the rest of the slots
// zeroes for the rest of the slots the other 4, which actually don't work on the client at all :D
for (uint32 r = 0; r < structs::MAX_PP_MEMSPELL - MAX_PP_MEMSPELL; r++)
{
outapp->WriteUInt32(0xFFFFFFFFU);
}
outapp->WriteUInt32(13); // Unknown count
outapp->WriteUInt32(13); // gem refresh counts
for (uint32 r = 0; r < 13; r++)
for (uint32 r = 0; r < MAX_PP_MEMSPELL; r++)
{
outapp->WriteUInt32(0); // Unknown
outapp->WriteUInt32(emu->spellSlotRefresh[r]); // spell gem refresh
}
outapp->WriteUInt32(0); // also refresh -- historically HT/LoH :P
outapp->WriteUInt8(0); // Unknown
@@ -2358,31 +2371,33 @@ namespace RoF2
for (uint32 r = 0; r < BUFF_COUNT; r++)
{
float instrument_mod = 0.0f;
uint8 slotid = emu->buffs[r].slotid;
uint8 effect_type = emu->buffs[r].effect_type;
uint32 player_id = emu->buffs[r].player_id;;
if (emu->buffs[r].spellid != 0xFFFF && emu->buffs[r].spellid != 0)
{
instrument_mod = 1.0f + (emu->buffs[r].bard_modifier - 10) / 10.0f;
slotid = 2;
effect_type = 2;
player_id = 0x000717fd;
}
else
{
slotid = 0;
effect_type = 0;
}
outapp->WriteUInt8(0); // Had this as slot, but always appears to be 0 on live.
// this is different than the client struct for some reason :P
// missing a few things, shuffled around
outapp->WriteUInt8(0); // this is an unknown
outapp->WriteFloat(instrument_mod);
outapp->WriteUInt32(player_id);
outapp->WriteUInt8(0);
outapp->WriteUInt32(emu->buffs[r].counters);
//outapp->WriteUInt8(emu->buffs[r].bard_modifier);
outapp->WriteUInt32(emu->buffs[r].duration);
outapp->WriteUInt8(emu->buffs[r].level);
outapp->WriteUInt32(emu->buffs[r].spellid);
outapp->WriteUInt32(slotid); // Only ever seen 2
outapp->WriteUInt8(effect_type); // Only ever seen 2
outapp->WriteUInt32(emu->buffs[r].num_hits);
outapp->WriteUInt32(0);
outapp->WriteUInt8(0);
outapp->WriteUInt32(emu->buffs[r].counters); // Appears twice ?
for (uint32 j = 0; j < 44; ++j)
@@ -3139,13 +3154,13 @@ namespace RoF2
eq_cse->Gender = emu_cse->Gender;
eq_cse->Face = emu_cse->Face;
for (int equip_index = 0; equip_index < EQEmu::legacy::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].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.Color = emu_cse->Equip[equip_index].Color.Color;
eq_cse->Equip[equip_index].Color = emu_cse->Equip[equip_index].Color;
}
eq_cse->Unknown15 = emu_cse->Unknown15;
@@ -4306,24 +4321,24 @@ namespace RoF2
if ((emu->NPC == 0) || (emu->race <= 12) || (emu->race == 128) || (emu->race == 130) || (emu->race == 330) || (emu->race == 522))
{
for (k = 0; k < 9; ++k)
for (k = EQEmu::textures::TextureBegin; k < EQEmu::textures::TextureCount; ++k)
{
{
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, emu->colors[k].Color);
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, emu->equipment_tint.Slot[k].Color);
}
}
structs::EquipStruct *Equipment = (structs::EquipStruct *)Buffer;
structs::Texture_Struct *Equipment = (structs::Texture_Struct *)Buffer;
for (k = 0; k < 9; k++) {
Equipment[k].Material = emu->equipment[k].Material;
Equipment[k].Unknown1 = emu->equipment[k].Unknown1;
Equipment[k].EliteMaterial = emu->equipment[k].EliteMaterial;
Equipment[k].HeroForgeModel = emu->equipment[k].HeroForgeModel;
Equipment[k].Material2 = emu->equipment[k].Material2;
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].EliteMaterial;
Equipment[k].HeroForgeModel = emu->equipment.Slot[k].HeroForgeModel;
Equipment[k].Material2 = emu->equipment.Slot[k].Material2;
}
Buffer += (sizeof(structs::EquipStruct) * 9);
Buffer += (sizeof(structs::Texture_Struct) * EQEmu::textures::TextureCount);
}
else
{
@@ -4333,13 +4348,13 @@ namespace RoF2
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0);
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0);
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, emu->equipment[EQEmu::legacy::MaterialPrimary].Material);
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, emu->equipment.Primary.Material);
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0);
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0);
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0);
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0);
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, emu->equipment[EQEmu::legacy::MaterialSecondary].Material);
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, emu->equipment.Secondary.Material);
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0);
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0);
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0);
@@ -4389,6 +4404,19 @@ namespace RoF2
delete in;
}
ENCODE(OP_CrystalCountUpdate)
{
ENCODE_LENGTH_EXACT(CrystalCountUpdate_Struct);
SETUP_DIRECT_ENCODE(CrystalCountUpdate_Struct, structs::CrystalCountUpdate_Struct);
OUT(CurrentRadiantCrystals);
OUT(CareerRadiantCrystals);
OUT(CurrentEbonCrystals);
OUT(CareerEbonCrystals);
FINISH_ENCODE();
}
// DECODE methods
DECODE(OP_AdventureMerchantSell)
@@ -4513,15 +4541,15 @@ namespace RoF2
DECODE(OP_Buff)
{
DECODE_LENGTH_EXACT(structs::SpellBuffFade_Struct_Live);
SETUP_DIRECT_DECODE(SpellBuffFade_Struct, structs::SpellBuffFade_Struct_Live);
DECODE_LENGTH_EXACT(structs::SpellBuffPacket_Struct);
SETUP_DIRECT_DECODE(SpellBuffPacket_Struct, structs::SpellBuffPacket_Struct);
IN(entityid);
//IN(slot);
IN(level);
IN(effect);
IN(spellid);
IN(duration);
IN(buff.effect_type);
IN(buff.level);
IN(buff.unknown003);
IN(buff.spellid);
IN(buff.duration);
IN(slotid);
IN(bufffade);
@@ -4547,10 +4575,7 @@ namespace RoF2
DECODE_LENGTH_EXACT(structs::CastSpell_Struct);
SETUP_DIRECT_DECODE(CastSpell_Struct, structs::CastSpell_Struct);
if (eq->slot == 13)
emu->slot = 10;
else
IN(slot);
emu->slot = static_cast<uint32>(RoF2ToServerCastingSlot(static_cast<CastingSlot>(eq->slot)));
IN(spell_id);
emu->inventoryslot = RoF2ToServerSlot(eq->inventory_slot);
@@ -5476,7 +5501,7 @@ namespace RoF2
void SerializeItem(EQEmu::OutBuffer& ob, const ItemInst *inst, int16 slot_id_in, uint8 depth, ItemPacketType packet_type)
{
const EQEmu::Item_Struct *item = inst->GetUnscaledItem();
const EQEmu::ItemBase *item = inst->GetUnscaledItem();
RoF2::structs::ItemSerializationHeader hdr;
@@ -5484,7 +5509,7 @@ namespace RoF2
snprintf(hdr.unknown000, sizeof(hdr.unknown000), "%016d", item->ID);
hdr.stacksize = (inst->IsStackable() ? ((inst->GetCharges() > 254) ? 0xFFFFFFFF : inst->GetCharges()) : 1);
hdr.stacksize = (inst->IsStackable() ? ((inst->GetCharges() > 1000) ? 0xFFFFFFFF : inst->GetCharges()) : 1);
hdr.unknown004 = 0;
structs::InventorySlot_Struct slot_id = ServerToRoF2Slot(slot_id_in, packet_type);
@@ -5926,11 +5951,11 @@ namespace RoF2
{
structs::InventorySlot_Struct RoF2Slot;
RoF2Slot.Type = INVALID_INDEX;
RoF2Slot.Unknown02 = NOT_USED;
RoF2Slot.Unknown02 = 0;
RoF2Slot.Slot = INVALID_INDEX;
RoF2Slot.SubIndex = INVALID_INDEX;
RoF2Slot.AugIndex = INVALID_INDEX;
RoF2Slot.Unknown01 = NOT_USED;
RoF2Slot.Unknown01 = 0;
uint32 TempSlot = 0;
@@ -6039,7 +6064,7 @@ namespace RoF2
RoF2Slot.Slot = INVALID_INDEX;
RoF2Slot.SubIndex = INVALID_INDEX;
RoF2Slot.AugIndex = INVALID_INDEX;
RoF2Slot.Unknown01 = NOT_USED;
RoF2Slot.Unknown01 = 0;
uint32 TempSlot = 0;
@@ -6287,4 +6312,80 @@ namespace RoF2
}
}
static inline CastingSlot ServerToRoF2CastingSlot(EQEmu::CastingSlot slot)
{
switch (slot) {
case EQEmu::CastingSlot::Gem1:
return CastingSlot::Gem1;
case EQEmu::CastingSlot::Gem2:
return CastingSlot::Gem2;
case EQEmu::CastingSlot::Gem3:
return CastingSlot::Gem3;
case EQEmu::CastingSlot::Gem4:
return CastingSlot::Gem4;
case EQEmu::CastingSlot::Gem5:
return CastingSlot::Gem5;
case EQEmu::CastingSlot::Gem6:
return CastingSlot::Gem6;
case EQEmu::CastingSlot::Gem7:
return CastingSlot::Gem7;
case EQEmu::CastingSlot::Gem8:
return CastingSlot::Gem8;
case EQEmu::CastingSlot::Gem9:
return CastingSlot::Gem9;
case EQEmu::CastingSlot::Gem10:
return CastingSlot::Gem10;
case EQEmu::CastingSlot::Gem11:
return CastingSlot::Gem11;
case EQEmu::CastingSlot::Gem12:
return CastingSlot::Gem12;
case EQEmu::CastingSlot::Item:
case EQEmu::CastingSlot::PotionBelt:
return CastingSlot::Item;
case EQEmu::CastingSlot::Discipline:
return CastingSlot::Discipline;
case EQEmu::CastingSlot::AltAbility:
return CastingSlot::AltAbility;
default: // we shouldn't have any issues with other slots ... just return something
return CastingSlot::Discipline;
}
}
static inline EQEmu::CastingSlot RoF2ToServerCastingSlot(CastingSlot slot)
{
switch (slot) {
case CastingSlot::Gem1:
return EQEmu::CastingSlot::Gem1;
case CastingSlot::Gem2:
return EQEmu::CastingSlot::Gem2;
case CastingSlot::Gem3:
return EQEmu::CastingSlot::Gem3;
case CastingSlot::Gem4:
return EQEmu::CastingSlot::Gem4;
case CastingSlot::Gem5:
return EQEmu::CastingSlot::Gem5;
case CastingSlot::Gem6:
return EQEmu::CastingSlot::Gem6;
case CastingSlot::Gem7:
return EQEmu::CastingSlot::Gem7;
case CastingSlot::Gem8:
return EQEmu::CastingSlot::Gem8;
case CastingSlot::Gem9:
return EQEmu::CastingSlot::Gem9;
case CastingSlot::Gem10:
return EQEmu::CastingSlot::Gem10;
case CastingSlot::Gem11:
return EQEmu::CastingSlot::Gem11;
case CastingSlot::Gem12:
return EQEmu::CastingSlot::Gem12;
case CastingSlot::Discipline:
return EQEmu::CastingSlot::Discipline;
case CastingSlot::Item:
return EQEmu::CastingSlot::Item;
case CastingSlot::AltAbility:
return EQEmu::CastingSlot::AltAbility;
default: // we shouldn't have any issues with other slots ... just return something
return EQEmu::CastingSlot::Discipline;
}
}
} /*RoF2*/
+18
View File
@@ -50,6 +50,24 @@ namespace RoF2
#include "rof2_ops.h"
};
enum class CastingSlot : uint32 {
Gem1 = 0,
Gem2 = 1,
Gem3 = 2,
Gem4 = 3,
Gem5 = 4,
Gem6 = 5,
Gem7 = 6,
Gem8 = 7,
Gem9 = 8,
Gem10 = 9,
Gem11 = 10,
Gem12 = 11,
Item = 12,
Discipline = 13,
AltAbility = 0xFF
};
}; /*RoF2*/
#endif /*COMMON_ROF2_H*/
+27 -9
View File
@@ -10,7 +10,7 @@
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.
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
@@ -22,7 +22,7 @@
#include "../string_util.h"
size_t RoF2::invtype::InvTypeSize(int inv_type)
size_t RoF2::invtype::GetInvTypeSize(int inv_type)
{
switch (inv_type) {
case invtype::InvTypePossessions:
@@ -80,7 +80,7 @@ size_t RoF2::invtype::InvTypeSize(int inv_type)
}
}
const char* RoF2::invtype::InvTypeName(int inv_type)
const char* RoF2::invtype::GetInvTypeName(int inv_type)
{
switch (inv_type) {
case invtype::InvTypeInvalid:
@@ -140,7 +140,25 @@ const char* RoF2::invtype::InvTypeName(int inv_type)
}
}
const char* RoF2::invslot::InvPossessionsSlotName(int inv_slot)
bool RoF2::invtype::IsInvTypePersistent(int inv_type)
{
switch (inv_type) {
case invtype::InvTypePossessions:
case invtype::InvTypeBank:
case invtype::InvTypeSharedBank:
case invtype::InvTypeTrade:
case invtype::InvTypeWorld:
case invtype::InvTypeLimbo:
case invtype::InvTypeTribute:
case invtype::InvTypeTrophyTribute:
case invtype::InvTypeGuildTribute:
return true;
default:
return false;
}
}
const char* RoF2::invslot::GetInvPossessionsSlotName(int inv_slot)
{
switch (inv_slot) {
case invslot::InvSlotInvalid:
@@ -218,12 +236,12 @@ const char* RoF2::invslot::InvPossessionsSlotName(int inv_slot)
}
}
const char* RoF2::invslot::InvSlotName(int inv_type, int inv_slot)
const char* RoF2::invslot::GetInvSlotName(int inv_type, int inv_slot)
{
if (inv_type == invtype::InvTypePossessions)
return invslot::InvPossessionsSlotName(inv_slot);
return invslot::GetInvPossessionsSlotName(inv_slot);
size_t type_size = invtype::InvTypeSize(inv_type);
size_t type_size = invtype::GetInvTypeSize(inv_type);
if (!type_size || inv_slot == invslot::InvSlotInvalid)
return "Invalid Slot";
@@ -237,7 +255,7 @@ const char* RoF2::invslot::InvSlotName(int inv_type, int inv_slot)
return ret_str.c_str();
}
const char* RoF2::invbag::InvBagIndexName(int bag_index)
const char* RoF2::invbag::GetInvBagIndexName(int bag_index)
{
if (bag_index == invbag::InvBagInvalid)
return "Invalid Bag";
@@ -251,7 +269,7 @@ const char* RoF2::invbag::InvBagIndexName(int bag_index)
return ret_str.c_str();
}
const char* RoF2::invaug::InvAugIndexName(int aug_index)
const char* RoF2::invaug::GetInvAugIndexName(int aug_index)
{
if (aug_index == invaug::InvAugInvalid)
return "Invalid Augment";
+35 -26
View File
@@ -10,7 +10,7 @@
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.
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
@@ -21,7 +21,7 @@
#define COMMON_ROF2_LIMITS_H
#include "../types.h"
#include "../client_version.h"
#include "../emu_versions.h"
#include "../skills.h"
@@ -32,8 +32,13 @@ namespace RoF2
enum : bool { False = false, True = true };
// pre-declarations
namespace inventory {
inline EQEmu::versions::ClientVersion GetInventoryRef() { return EQEmu::versions::ClientVersion::RoF2; }
} /*inventory*/
namespace invtype {
inline EQEmu::versions::ClientVersion InvTypeRef() { return EQEmu::versions::ClientVersion::RoF2; }
inline EQEmu::versions::ClientVersion GetInvTypeRef() { return EQEmu::versions::ClientVersion::RoF2; }
enum : int { InvTypeInvalid = -1, InvTypeBegin };
@@ -69,7 +74,7 @@ namespace RoF2
} /*invtype*/
namespace invslot {
inline EQEmu::versions::ClientVersion InvSlotRef() { return EQEmu::versions::ClientVersion::RoF2; }
inline EQEmu::versions::ClientVersion GetInvSlotRef() { return EQEmu::versions::ClientVersion::RoF2; }
enum : int { InvSlotInvalid = -1, InvSlotBegin };
@@ -122,21 +127,21 @@ namespace RoF2
} /*invslot*/
namespace invbag {
inline EQEmu::versions::ClientVersion InvBagRef() { return EQEmu::versions::ClientVersion::RoF2; }
inline EQEmu::versions::ClientVersion GetInvBagRef() { return EQEmu::versions::ClientVersion::RoF2; }
enum : int { InvBagInvalid = -1, InvBagBegin };
} /*invbag*/
namespace invaug {
inline EQEmu::versions::ClientVersion InvAugRef() { return EQEmu::versions::ClientVersion::RoF2; }
inline EQEmu::versions::ClientVersion GetInvAugRef() { return EQEmu::versions::ClientVersion::RoF2; }
enum : int { InvAugInvalid = -1, InvAugBegin };
} /*invaug*/
namespace item {
inline EQEmu::versions::ClientVersion ItemRef() { return EQEmu::versions::ClientVersion::RoF2; }
inline EQEmu::versions::ClientVersion GetItemRef() { return EQEmu::versions::ClientVersion::RoF2; }
//enum Unknown : int { // looks like item class..but, RoF has it too - nothing in UF-
// Unknown1 = 0,
@@ -165,27 +170,37 @@ namespace RoF2
} /*item*/
namespace profile {
inline EQEmu::versions::ClientVersion ProfileRef() { return EQEmu::versions::ClientVersion::RoF2; }
inline EQEmu::versions::ClientVersion GetProfileRef() { return EQEmu::versions::ClientVersion::RoF2; }
} /*profile*/
namespace constants {
inline EQEmu::versions::ClientVersion ConstantsRef() { return EQEmu::versions::ClientVersion::RoF2; }
inline EQEmu::versions::ClientVersion GetConstantsRef() { return EQEmu::versions::ClientVersion::RoF2; }
} /*constants*/
namespace behavior {
inline EQEmu::versions::ClientVersion BehaviorRef() { return EQEmu::versions::ClientVersion::RoF2; }
inline EQEmu::versions::ClientVersion GetBehaviorRef() { return EQEmu::versions::ClientVersion::RoF2; }
} /*behavior*/
namespace skills {
inline EQEmu::versions::ClientVersion SkillsRef() { return EQEmu::versions::ClientVersion::RoF2; }
inline EQEmu::versions::ClientVersion GetSkillsRef() { return EQEmu::versions::ClientVersion::RoF2; }
} /*skills*/
// declarations
namespace inventory {
const bool ConcatenateInvTypeLimbo = false;
const bool AllowOverLevelEquipment = true;
const bool AllowEmptyBagInBag = true;
const bool AllowClickCastFromBag = true;
} /*inventory*/
namespace invtype {
const size_t InvTypePossessionsSize = invslot::PossessionsCount;
const size_t InvTypeBankSize = 24;
@@ -195,7 +210,7 @@ namespace RoF2
const size_t InvTypeLimboSize = 36;
const size_t InvTypeTributeSize = 5;
const size_t InvTypeTrophyTributeSize = 0;//unknown
const size_t InvTypeGuildTributeSize = 0;//unknown
const size_t InvTypeGuildTributeSize = 2;//unverified
const size_t InvTypeMerchantSize = 200;
const size_t InvTypeDeletedSize = 0;//unknown - "Recovery Tab"
const size_t InvTypeCorpseSize = InvTypePossessionsSize;
@@ -213,30 +228,30 @@ namespace RoF2
const size_t InvTypeKronoSize = 0;//unknown
const size_t InvTypeOtherSize = 0;//unknown
const size_t NPCTradeSize = 4;
extern size_t GetInvTypeSize(int inv_type);
extern const char* GetInvTypeName(int inv_type);
extern size_t InvTypeSize(int inv_type);
extern const char* InvTypeName(int inv_type);
extern bool IsInvTypePersistent(int inv_type);
} /*invtype*/
namespace invslot {
extern const char* InvPossessionsSlotName(int inv_slot);
extern const char* InvSlotName(int inv_type, int inv_slot);
extern const char* GetInvPossessionsSlotName(int inv_slot);
extern const char* GetInvSlotName(int inv_type, int inv_slot);
} /*invslot*/
namespace invbag {
const size_t ItemBagSize = 255; // server Size will be 255..unsure what actual client is (test)
extern const char* InvBagIndexName(int bag_index);
extern const char* GetInvBagIndexName(int bag_index);
} /*invbag*/
namespace invaug {
const size_t ItemAugSize = 6;
extern const char* InvAugIndexName(int aug_index);
extern const char* GetInvAugIndexName(int aug_index);
} /*invaug*/
@@ -246,6 +261,7 @@ namespace RoF2
namespace profile {
const size_t TributeSize = invtype::InvTypeTributeSize;
const size_t GuildTributeSize = invtype::InvTypeGuildTributeSize;
const size_t BandoliersSize = 20; // number of bandolier instances
const size_t BandolierItemCount = 4; // number of equipment slots in bandolier instance
@@ -264,13 +280,6 @@ namespace RoF2
} /*constants*/
namespace behavior {
const bool ConcatenateInvTypeLimbo = false;
const bool AllowOverLevelEquipment = true;
const bool AllowEmptyBagInBag = true;
const bool AllowClickCastFromBag = true;
const bool CoinHasWeight = false;
} /*behavior*/
+1
View File
@@ -141,6 +141,7 @@ E(OP_ZoneEntry)
E(OP_ZonePlayerToBind)
E(OP_ZoneServerInfo)
E(OP_ZoneSpawns)
E(OP_CrystalCountUpdate)
// Begin RoF Decodes
D(OP_AdventureMerchantSell)
D(OP_AltCurrencySell)
+121 -156
View File
@@ -163,7 +163,7 @@ struct AdventureInfo {
** Merth: Gave struct a name so gcc 2.96 would compile
**
*/
struct Color_Struct
struct Tint_Struct
{
union {
struct {
@@ -171,21 +171,65 @@ struct Color_Struct
uint8 Green;
uint8 Red;
uint8 UseTint; // if there's a tint this is FF
} RGB;
};
uint32 Color;
};
};
struct CharSelectEquip
struct TintProfile
{
union {
struct {
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;
};
Tint_Struct Slot[EQEmu::textures::TextureCount];
};
};
/*
* Visible equiptment.
* Size: 20 Octets
*/
struct Texture_Struct
{
uint32 Material;
uint32 Unknown1;
uint32 EliteMaterial;
uint32 HeroForgeModel;
uint32 Material2;
Color_Struct Color;
uint32 Material2; // Same as material?
};
// Needs more research regarding new slots
//struct TextureProfile
//{
// union {
// struct {
// 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;
// };
// Texture_Struct Slot[EQEmu::textures::TextureCount];
// };
//
// TextureProfile();
//};
struct CharSelectEquip : Texture_Struct, Tint_Struct {};
struct CharacterSelectEntry_Struct
{
/*0000*/ char Name[1]; // Name null terminated
@@ -231,21 +275,6 @@ struct CharacterSelect_Struct
/*004*/ CharacterSelectEntry_Struct Entries[0];
};
/*
* Visible equiptment.
* Size: 20 Octets
*/
struct EquipStruct
{
/*00*/ uint32 Material;
/*04*/ uint32 Unknown1;
/*08*/ uint32 EliteMaterial;
/*12*/ uint32 HeroForgeModel;
/*16*/ uint32 Material2; // Same as material?
/*20*/
};
struct Membership_Entry_Struct
{
/*000*/ uint32 purchase_id; // Seen 1, then increments 90287 to 90300
@@ -447,39 +476,24 @@ struct Spawn_Struct
/*0000*/ uint32 unknown18;
/*0000*/ uint32 unknown19;
Spawn_Struct_Position Position;
/*0000*/ union
{
struct
{
/*0000*/ Color_Struct color_helmet; // Color of helmet item
/*0000*/ Color_Struct color_chest; // Color of chest item
/*0000*/ Color_Struct color_arms; // Color of arms item
/*0000*/ Color_Struct color_bracers; // Color of bracers item
/*0000*/ Color_Struct color_hands; // Color of hands item
/*0000*/ Color_Struct color_legs; // Color of legs item
/*0000*/ Color_Struct color_feet; // Color of feet item
/*0000*/ Color_Struct color_primary; // Color of primary item
/*0000*/ Color_Struct color_secondary; // Color of secondary item
} equipment_colors;
/*0000*/ Color_Struct colors[9]; // Array elements correspond to struct equipment_colors above
};
/*0000*/ TintProfile equipment_tint;
// skip these bytes if not a valid player race
/*0000*/ union
{
struct
{
/*0000*/ EquipStruct equip_helmet; // Equiptment: Helmet visual
/*0000*/ EquipStruct equip_chest; // Equiptment: Chest visual
/*0000*/ EquipStruct equip_arms; // Equiptment: Arms visual
/*0000*/ EquipStruct equip_bracers; // Equiptment: Wrist visual
/*0000*/ EquipStruct equip_hands; // Equiptment: Hands visual
/*0000*/ EquipStruct equip_legs; // Equiptment: Legs visual
/*0000*/ EquipStruct equip_feet; // Equiptment: Boots visual
/*0000*/ EquipStruct equip_primary; // Equiptment: Main visual
/*0000*/ EquipStruct equip_secondary; // Equiptment: Off visual
/*0000*/ Texture_Struct equip_helmet; // Equiptment: Helmet visual
/*0000*/ Texture_Struct equip_chest; // Equiptment: Chest visual
/*0000*/ Texture_Struct equip_arms; // Equiptment: Arms visual
/*0000*/ Texture_Struct equip_bracers; // Equiptment: Wrist visual
/*0000*/ Texture_Struct equip_hands; // Equiptment: Hands visual
/*0000*/ Texture_Struct equip_legs; // Equiptment: Legs visual
/*0000*/ Texture_Struct equip_feet; // Equiptment: Boots visual
/*0000*/ Texture_Struct equip_primary; // Equiptment: Main visual
/*0000*/ Texture_Struct equip_secondary; // Equiptment: Off visual
} equip;
/*0000*/ EquipStruct equipment[9];
/*0000*/ Texture_Struct equipment[9];
};
/*0000*/ //char title[0]; // only read if(hasTitleOrSuffix & 4)
@@ -621,7 +635,7 @@ struct MemorizeSpell_Struct {
uint32 slot; // Spot in the spell book/memorized slot
uint32 spell_id; // Spell id (200 or c8 is minor healing, etc)
uint32 scribing; // 1 if memorizing a spell, set to 0 if scribing to book, 2 if un-memming
uint32 unknown12;
uint32 reduction; // lowers reuse
};
/*
@@ -654,11 +668,12 @@ struct DeleteSpell_Struct
struct ManaChange_Struct
{
uint32 new_mana; // New Mana AMount
uint32 stamina;
uint32 spell_id;
uint32 unknown12;
uint32 unknown16;
/*00*/ uint32 new_mana; // New Mana AMount
/*04*/ uint32 stamina;
/*08*/ uint32 spell_id;
/*12*/ uint8 keepcasting; // won't stop the cast. Change mana while casting?
/*13*/ uint8 padding[3]; // client doesn't read it, garbage data seems like
/*16*/ int32 slot; // -1 for normal usage slot for when we want silent interrupt? I think it does timer stuff or something. Linked Spell Reuse interrupt uses it
};
struct SwapSpell_Struct
@@ -705,69 +720,31 @@ struct SpawnAppearance_Struct
struct SpellBuff_Struct
{
/*000*/ uint8 slotid; // badly named... seems to be 2 for a real buff, 0 otherwise
/*001*/ float unknown004; // Seen 1 for no buff
/*005*/ uint32 player_id; // 'global' ID of the caster, for wearoff messages
/*009*/ uint32 unknown016;
/*013*/ uint8 bard_modifier;
/*014*/ int32 duration;
/*018*/ uint8 level;
/*019*/ uint32 spellid;
/*023*/ uint32 counters;
/*027*/ uint8 unknown0028[53];
/*080*/
};
struct SpellBuff_Struct_Old
{
/*000*/ uint8 slotid; // badly named... seems to be 2 for a real buff, 0 otherwise
/*001*/ uint8 level;
/*002*/ uint8 bard_modifier;
/*003*/ uint8 effect; // not real
/*004*/ float unknown004; // Seen 1 for no buff
/*008*/ uint32 spellid;
/*012*/ int32 duration;
/*016*/ uint32 unknown016;
/*020*/ uint32 player_id; // 'global' ID of the caster, for wearoff messages
/*024*/ uint32 counters;
/*028*/ uint8 unknown0028[60];
/*000*/ uint8 effect_type; // 0 = no buff, 2 = buff, 4 = inverse affects of buff
/*001*/ uint8 level; // Seen 1 for no buff
/*002*/ uint8 unknown002; //pretty sure padding now
/*003*/ uint8 unknown003; // MQ2 used to call this "damage shield" -- don't see client referencing it, so maybe server side DS type tracking?
/*004*/ float bard_modifier;
/*008*/ uint32 spellid;
/*012*/ uint32 duration;
/*016*/ uint32 player_id; // caster ID, pretty sure just zone ID
/*020*/ uint32 num_hits;
/*024*/ float y; // referenced by SPA 441
/*028*/ float x; // unsure if all buffs get them
/*032*/ float z; // as valid data
/*036*/ uint32 unknown036;
/*040*/ int32 slot_data[12]; // book keeping stuff per slot (counters, rune/vie)
/*088*/
};
// Not functional yet, but this is what the packet looks like on Live
struct SpellBuffFade_Struct_Live {
/*000*/ uint32 entityid; // Player id who cast the buff
/*004*/ uint8 unknown004;
/*005*/ uint8 level;
/*006*/ uint8 effect;
/*007*/ uint8 unknown007;
/*008*/ float unknown008;
/*012*/ uint32 spellid;
/*016*/ int32 duration;
/*020*/ uint32 playerId; // Global player ID?
/*024*/ uint32 num_hits;
/*028*/ uint8 unknown0028[64];
struct SpellBuffPacket_Struct {
/*000*/ uint32 entityid; // Player id who cast the buff
/*004*/ SpellBuff_Struct buff;
/*092*/ uint32 slotid;
/*096*/ uint32 bufffade;
/*100*/
};
struct SpellBuffFade_Struct {
/*000*/ uint32 entityid;
/*004*/ uint8 slot;
/*005*/ uint8 level;
/*006*/ uint8 effect;
/*007*/ uint8 unknown7;
/*008*/ uint32 spellid;
/*012*/ int32 duration;
/*016*/ uint32 num_hits;
/*020*/ uint32 unknown020; // Global player ID?
/*024*/ uint32 playerId; // Player id who cast the buff
/*028*/ uint32 slotid;
/*032*/ uint32 bufffade;
/*036*/
};
struct BuffRemoveRequest_Struct
{
/*00*/ uint32 SlotID;
@@ -1078,38 +1055,38 @@ union
{
struct
{
/*00184*/ EquipStruct equip_helmet; // Equipment: Helmet visual
/*00204*/ EquipStruct equip_chest; // Equipment: Chest visual
/*00224*/ EquipStruct equip_arms; // Equipment: Arms visual
/*00244*/ EquipStruct equip_bracers; // Equipment: Wrist visual
/*00264*/ EquipStruct equip_hands; // Equipment: Hands visual
/*00284*/ EquipStruct equip_legs; // Equipment: Legs visual
/*00304*/ EquipStruct equip_feet; // Equipment: Boots visual
/*00324*/ EquipStruct equip_primary; // Equipment: Main visual
/*00344*/ EquipStruct equip_secondary; // Equipment: Off visual
/*00184*/ Texture_Struct equip_helmet; // Equipment: Helmet visual
/*00204*/ Texture_Struct equip_chest; // Equipment: Chest visual
/*00224*/ Texture_Struct equip_arms; // Equipment: Arms visual
/*00244*/ Texture_Struct equip_bracers; // Equipment: Wrist visual
/*00264*/ Texture_Struct equip_hands; // Equipment: Hands visual
/*00284*/ Texture_Struct equip_legs; // Equipment: Legs visual
/*00304*/ Texture_Struct equip_feet; // Equipment: Boots visual
/*00324*/ Texture_Struct equip_primary; // Equipment: Main visual
/*00344*/ Texture_Struct equip_secondary; // Equipment: Off visual
// Below slots are just guesses, but all 0s anyway...
/*00364*/ EquipStruct equip_charm; // Equipment: Non-visual
/*00384*/ EquipStruct equip_ear1; // Equipment: Non-visual
/*00404*/ EquipStruct equip_ear2; // Equipment: Non-visual
/*00424*/ EquipStruct equip_face; // Equipment: Non-visual
/*00444*/ EquipStruct equip_neck; // Equipment: Non-visual
/*00464*/ EquipStruct equip_shoulder; // Equipment: Non-visual
/*00484*/ EquipStruct equip_bracer2; // Equipment: Non-visual
/*00504*/ EquipStruct equip_range; // Equipment: Non-visual
/*00524*/ EquipStruct equip_ring1; // Equipment: Non-visual
/*00544*/ EquipStruct equip_ring2; // Equipment: Non-visual
/*00564*/ EquipStruct equip_waist; // Equipment: Non-visual
/*00584*/ EquipStruct equip_powersource;// Equipment: Non-visual
/*00604*/ EquipStruct equip_ammo; // Equipment: Non-visual
/*00364*/ Texture_Struct equip_charm; // Equipment: Non-visual
/*00384*/ Texture_Struct equip_ear1; // Equipment: Non-visual
/*00404*/ Texture_Struct equip_ear2; // Equipment: Non-visual
/*00424*/ Texture_Struct equip_face; // Equipment: Non-visual
/*00444*/ Texture_Struct equip_neck; // Equipment: Non-visual
/*00464*/ Texture_Struct equip_shoulder; // Equipment: Non-visual
/*00484*/ Texture_Struct equip_bracer2; // Equipment: Non-visual
/*00504*/ Texture_Struct equip_range; // Equipment: Non-visual
/*00524*/ Texture_Struct equip_ring1; // Equipment: Non-visual
/*00544*/ Texture_Struct equip_ring2; // Equipment: Non-visual
/*00564*/ Texture_Struct equip_waist; // Equipment: Non-visual
/*00584*/ Texture_Struct equip_powersource;// Equipment: Non-visual
/*00604*/ Texture_Struct equip_ammo; // Equipment: Non-visual
} equip;
/*00184*/ EquipStruct equipment[22]; // Total Slots
/*00184*/ Texture_Struct equipment[22]; // Total Slots
};
/*00624*/ uint32 equip2_count; // Seen 9
/*00628*/ EquipStruct equipment2[EQEmu::legacy::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*/ Color_Struct item_tint[EQEmu::legacy::MaterialCount]; // RR GG BB 00
/*00812*/ TintProfile item_tint; // RR GG BB 00
/*00848*/ uint32 tint_count2; // Seen 9
/*00852*/ Color_Struct item_tint2[EQEmu::legacy::MaterialCount]; // RR GG BB 00
/*00852*/ TintProfile item_tint2; // RR GG BB 00
/*00888*/ uint8 haircolor; // Player hair color
/*00889*/ uint8 beardcolor; // Player beard color
/*00890*/ uint32 unknown_rof5; //
@@ -1385,7 +1362,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 RoF2
/*022*/ Color_Struct color;
/*022*/ Tint_Struct color;
/*026*/ uint8 wear_slot_id;
/*027*/
};
@@ -2446,7 +2423,7 @@ struct AdventureLeaderboard_Struct
/*struct Item_Shop_Struct {
uint16 merchantid;
uint8 itemtype;
Item_Struct item;
ItemBase item;
uint8 iss_unknown001[6];
};*/
@@ -3634,27 +3611,6 @@ struct PetitionBug_Struct{
char text[1028];
};
struct DyeStruct
{
union
{
struct
{
struct Color_Struct head;
struct Color_Struct chest;
struct Color_Struct arms;
struct Color_Struct wrists;
struct Color_Struct hands;
struct Color_Struct legs;
struct Color_Struct feet;
struct Color_Struct primary; // you can't actually dye this
struct Color_Struct secondary; // or this
}
dyes;
struct Color_Struct dye[9];
};
};
struct ApproveZone_Struct {
char name[64];
uint32 zoneid;
@@ -5088,6 +5044,15 @@ struct MercenaryMerchantResponse_Struct {
/*0004*/
};
// Sent by Server to update character crystals.
struct CrystalCountUpdate_Struct
{
/*000*/ uint32 CurrentRadiantCrystals;
/*004*/ uint32 CareerRadiantCrystals;
/*008*/ uint32 CurrentEbonCrystals;
/*012*/ uint32 CareerEbonCrystals;
};
}; /*structs*/
}; /*RoF2*/
+27 -9
View File
@@ -10,7 +10,7 @@
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.
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
@@ -22,7 +22,7 @@
#include "../string_util.h"
size_t RoF::invtype::InvTypeSize(int inv_type)
size_t RoF::invtype::GetInvTypeSize(int inv_type)
{
switch (inv_type) {
case invtype::InvTypePossessions:
@@ -78,7 +78,7 @@ size_t RoF::invtype::InvTypeSize(int inv_type)
}
}
const char* RoF::invtype::InvTypeName(int inv_type)
const char* RoF::invtype::GetInvTypeName(int inv_type)
{
switch (inv_type) {
case invtype::InvTypeInvalid:
@@ -136,7 +136,25 @@ const char* RoF::invtype::InvTypeName(int inv_type)
}
}
const char* RoF::invslot::InvPossessionsSlotName(int inv_slot)
bool RoF::invtype::IsInvTypePersistent(int inv_type)
{
switch (inv_type) {
case invtype::InvTypePossessions:
case invtype::InvTypeBank:
case invtype::InvTypeSharedBank:
case invtype::InvTypeTrade:
case invtype::InvTypeWorld:
case invtype::InvTypeLimbo:
case invtype::InvTypeTribute:
case invtype::InvTypeTrophyTribute:
case invtype::InvTypeGuildTribute:
return true;
default:
return false;
}
}
const char* RoF::invslot::GetInvPossessionsSlotName(int inv_slot)
{
switch (inv_slot) {
case invslot::InvSlotInvalid:
@@ -214,12 +232,12 @@ const char* RoF::invslot::InvPossessionsSlotName(int inv_slot)
}
}
const char* RoF::invslot::InvSlotName(int inv_type, int inv_slot)
const char* RoF::invslot::GetInvSlotName(int inv_type, int inv_slot)
{
if (inv_type == invtype::InvTypePossessions)
return invslot::InvPossessionsSlotName(inv_slot);
return invslot::GetInvPossessionsSlotName(inv_slot);
size_t type_size = invtype::InvTypeSize(inv_type);
size_t type_size = invtype::GetInvTypeSize(inv_type);
if (!type_size || inv_slot == invslot::InvSlotInvalid)
return "Invalid Slot";
@@ -233,7 +251,7 @@ const char* RoF::invslot::InvSlotName(int inv_type, int inv_slot)
return ret_str.c_str();
}
const char* RoF::invbag::InvBagIndexName(int bag_index)
const char* RoF::invbag::GetInvBagIndexName(int bag_index)
{
if (bag_index == invbag::InvBagInvalid)
return "Invalid Bag";
@@ -247,7 +265,7 @@ const char* RoF::invbag::InvBagIndexName(int bag_index)
return ret_str.c_str();
}
const char* RoF::invaug::InvAugIndexName(int aug_index)
const char* RoF::invaug::GetInvAugIndexName(int aug_index)
{
if (aug_index == invaug::InvAugInvalid)
return "Invalid Augment";
+35 -26
View File
@@ -10,7 +10,7 @@
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.
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
@@ -21,7 +21,7 @@
#define COMMON_ROF_LIMITS_H
#include "../types.h"
#include "../client_version.h"
#include "../emu_versions.h"
#include "../skills.h"
@@ -32,8 +32,13 @@ namespace RoF
enum : bool { False = false, True = true };
// pre-declarations
namespace inventory {
inline EQEmu::versions::ClientVersion GetInventoryRef() { return EQEmu::versions::ClientVersion::RoF; }
} /*inventory*/
namespace invtype {
inline EQEmu::versions::ClientVersion InvTypeRef() { return EQEmu::versions::ClientVersion::RoF; }
inline EQEmu::versions::ClientVersion GetInvTypeRef() { return EQEmu::versions::ClientVersion::RoF; }
enum : int { InvTypeInvalid = -1, InvTypeBegin };
@@ -68,7 +73,7 @@ namespace RoF
} /*invtype*/
namespace invslot {
inline EQEmu::versions::ClientVersion InvSlotRef() { return EQEmu::versions::ClientVersion::RoF; }
inline EQEmu::versions::ClientVersion GetInvSlotRef() { return EQEmu::versions::ClientVersion::RoF; }
enum : int { InvSlotInvalid = -1, InvSlotBegin };
@@ -121,21 +126,21 @@ namespace RoF
} /*invslot*/
namespace invbag {
inline EQEmu::versions::ClientVersion InvBagRef() { return EQEmu::versions::ClientVersion::RoF; }
inline EQEmu::versions::ClientVersion GetInvBagRef() { return EQEmu::versions::ClientVersion::RoF; }
enum : int { InvBagInvalid = -1, InvBagBegin };
} /*invbag*/
namespace invaug {
inline EQEmu::versions::ClientVersion InvAugRef() { return EQEmu::versions::ClientVersion::RoF; }
inline EQEmu::versions::ClientVersion GetInvAugRef() { return EQEmu::versions::ClientVersion::RoF; }
enum : int { InvAugInvalid = -1, InvAugBegin };
} /*invaug*/
namespace item {
inline EQEmu::versions::ClientVersion ItemRef() { return EQEmu::versions::ClientVersion::RoF; }
inline EQEmu::versions::ClientVersion GetItemRef() { return EQEmu::versions::ClientVersion::RoF; }
enum ItemPacketType : int {
ItemPacketMerchant = 100,
@@ -157,27 +162,37 @@ namespace RoF
} /*item*/
namespace profile {
inline EQEmu::versions::ClientVersion ProfileRef() { return EQEmu::versions::ClientVersion::RoF; }
inline EQEmu::versions::ClientVersion GetProfileRef() { return EQEmu::versions::ClientVersion::RoF; }
} /*profile*/
namespace constants {
inline EQEmu::versions::ClientVersion ConstantsRef() { return EQEmu::versions::ClientVersion::RoF; }
inline EQEmu::versions::ClientVersion GetConstantsRef() { return EQEmu::versions::ClientVersion::RoF; }
} /*constants*/
namespace behavior {
inline EQEmu::versions::ClientVersion BehaviorRef() { return EQEmu::versions::ClientVersion::RoF; }
inline EQEmu::versions::ClientVersion GetBehaviorRef() { return EQEmu::versions::ClientVersion::RoF; }
} /*behavior*/
namespace skills {
inline EQEmu::versions::ClientVersion SkillsRef() { return EQEmu::versions::ClientVersion::RoF; }
inline EQEmu::versions::ClientVersion GetSkillsRef() { return EQEmu::versions::ClientVersion::RoF; }
} /*skills*/
// declarations
namespace inventory {
const bool ConcatenateInvTypeLimbo = false;
const bool AllowOverLevelEquipment = true;
const bool AllowEmptyBagInBag = true;
const bool AllowClickCastFromBag = true;
} /*inventory*/
namespace invtype {
const size_t InvTypePossessionsSize = invslot::PossessionsCount;
const size_t InvTypeBankSize = 24;
@@ -187,7 +202,7 @@ namespace RoF
const size_t InvTypeLimboSize = 36;
const size_t InvTypeTributeSize = 5;
const size_t InvTypeTrophyTributeSize = 0;//unknown
const size_t InvTypeGuildTributeSize = 0;//unknown
const size_t InvTypeGuildTributeSize = 2;//unverified
const size_t InvTypeMerchantSize = 200;
const size_t InvTypeDeletedSize = 0;//unknown - "Recovery Tab"
const size_t InvTypeCorpseSize = InvTypePossessionsSize;
@@ -204,30 +219,30 @@ namespace RoF
const size_t InvTypeGuildTrophyTributeSize = 0;//unknown
const size_t InvTypeOtherSize = 0;//unknown
const size_t NPCTradeSize = 4;
extern size_t GetInvTypeSize(int inv_type);
extern const char* GetInvTypeName(int inv_type);
extern size_t InvTypeSize(int inv_type);
extern const char* InvTypeName(int inv_type);
extern bool IsInvTypePersistent(int inv_type);
} /*invtype*/
namespace invslot {
extern const char* InvPossessionsSlotName(int inv_slot);
extern const char* InvSlotName(int inv_type, int inv_slot);
extern const char* GetInvPossessionsSlotName(int inv_slot);
extern const char* GetInvSlotName(int inv_type, int inv_slot);
} /*invslot*/
namespace invbag {
const size_t ItemBagSize = 255; // server Size will be 255..unsure what actual client is (test)
extern const char* InvBagIndexName(int bag_index);
extern const char* GetInvBagIndexName(int bag_index);
} /*invbag*/
namespace invaug {
const size_t ItemAugSize = 6;
extern const char* InvAugIndexName(int aug_index);
extern const char* GetInvAugIndexName(int aug_index);
} /*invaug*/
@@ -237,6 +252,7 @@ namespace RoF
namespace profile {
const size_t TributeSize = invtype::InvTypeTributeSize;
const size_t GuildTributeSize = invtype::InvTypeGuildTributeSize;
const size_t BandoliersSize = 20; // number of bandolier instances
const size_t BandolierItemCount = 4; // number of equipment slots in bandolier instance
@@ -255,13 +271,6 @@ namespace RoF
} /*constants*/
namespace behavior {
const bool ConcatenateInvTypeLimbo = false;
const bool AllowOverLevelEquipment = true;
const bool AllowEmptyBagInBag = true;
const bool AllowClickCastFromBag = true;
const bool CoinHasWeight = false;
} /*behavior*/
+112 -156
View File
@@ -163,7 +163,7 @@ struct AdventureInfo {
** Merth: Gave struct a name so gcc 2.96 would compile
**
*/
struct Color_Struct
struct Tint_Struct
{
union {
struct {
@@ -171,21 +171,65 @@ struct Color_Struct
uint8 Green;
uint8 Red;
uint8 UseTint; // if there's a tint this is FF
} RGB;
};
uint32 Color;
};
};
struct CharSelectEquip
struct TintProfile
{
union {
struct {
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;
};
Tint_Struct Slot[EQEmu::textures::TextureCount];
};
};
/*
* Visible equiptment.
* Size: 20 Octets
*/
struct Texture_Struct
{
uint32 Material;
uint32 Unknown1;
uint32 EliteMaterial;
uint32 HeroForgeModel;
uint32 Material2;
Color_Struct Color;
uint32 Material2; // Same as material?
};
// Needs more research regarding new slots
//struct TextureProfile
//{
// union {
// struct {
// 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;
// };
// Texture_Struct Slot[EQEmu::textures::TextureCount];
// };
//
// TextureProfile();
//};
struct CharSelectEquip : Texture_Struct, Tint_Struct {};
struct CharacterSelectEntry_Struct
{
/*0000*/ char Name[1]; // Name null terminated
@@ -231,21 +275,6 @@ struct CharacterSelect_Struct
/*004*/ CharacterSelectEntry_Struct Entries[0];
};
/*
* Visible equiptment.
* Size: 20 Octets
*/
struct EquipStruct
{
/*00*/ uint32 Material;
/*04*/ uint32 Unknown1;
/*08*/ uint32 EliteMaterial;
/*12*/ uint32 HeroForgeModel;
/*16*/ uint32 Material2; // Same as material?
/*20*/
};
struct Membership_Entry_Struct
{
/*000*/ uint32 purchase_id; // Seen 1, then increments 90287 to 90300
@@ -441,39 +470,24 @@ struct Spawn_Struct
/*0000*/ uint32 unknown18;
/*0000*/ uint32 unknown19;
Spawn_Struct_Position Position;
/*0000*/ union
{
struct
{
/*0000*/ Color_Struct color_helmet; // Color of helmet item
/*0000*/ Color_Struct color_chest; // Color of chest item
/*0000*/ Color_Struct color_arms; // Color of arms item
/*0000*/ Color_Struct color_bracers; // Color of bracers item
/*0000*/ Color_Struct color_hands; // Color of hands item
/*0000*/ Color_Struct color_legs; // Color of legs item
/*0000*/ Color_Struct color_feet; // Color of feet item
/*0000*/ Color_Struct color_primary; // Color of primary item
/*0000*/ Color_Struct color_secondary; // Color of secondary item
} equipment_colors;
/*0000*/ Color_Struct colors[9]; // Array elements correspond to struct equipment_colors above
};
/*0000*/ TintProfile equipment_tint;
// skip these bytes if not a valid player race
/*0000*/ union
{
struct
{
/*0000*/ EquipStruct equip_helmet; // Equiptment: Helmet visual
/*0000*/ EquipStruct equip_chest; // Equiptment: Chest visual
/*0000*/ EquipStruct equip_arms; // Equiptment: Arms visual
/*0000*/ EquipStruct equip_bracers; // Equiptment: Wrist visual
/*0000*/ EquipStruct equip_hands; // Equiptment: Hands visual
/*0000*/ EquipStruct equip_legs; // Equiptment: Legs visual
/*0000*/ EquipStruct equip_feet; // Equiptment: Boots visual
/*0000*/ EquipStruct equip_primary; // Equiptment: Main visual
/*0000*/ EquipStruct equip_secondary; // Equiptment: Off visual
/*0000*/ Texture_Struct equip_helmet; // Equiptment: Helmet visual
/*0000*/ Texture_Struct equip_chest; // Equiptment: Chest visual
/*0000*/ Texture_Struct equip_arms; // Equiptment: Arms visual
/*0000*/ Texture_Struct equip_bracers; // Equiptment: Wrist visual
/*0000*/ Texture_Struct equip_hands; // Equiptment: Hands visual
/*0000*/ Texture_Struct equip_legs; // Equiptment: Legs visual
/*0000*/ Texture_Struct equip_feet; // Equiptment: Boots visual
/*0000*/ Texture_Struct equip_primary; // Equiptment: Main visual
/*0000*/ Texture_Struct equip_secondary; // Equiptment: Off visual
} equip;
/*0000*/ EquipStruct equipment[9];
/*0000*/ Texture_Struct equipment[9];
};
/*0000*/ //char title[0]; // only read if(hasTitleOrSuffix & 4)
@@ -610,7 +624,7 @@ struct MemorizeSpell_Struct {
uint32 slot; // Spot in the spell book/memorized slot
uint32 spell_id; // Spell id (200 or c8 is minor healing, etc)
uint32 scribing; // 1 if memorizing a spell, set to 0 if scribing to book, 2 if un-memming
uint32 unknown12;
uint32 reduction; // lowers reuse
};
/*
@@ -643,11 +657,12 @@ struct DeleteSpell_Struct
struct ManaChange_Struct
{
uint32 new_mana; // New Mana AMount
uint32 stamina;
uint32 spell_id;
uint32 unknown12;
uint32 unknown16;
/*00*/ uint32 new_mana; // New Mana AMount
/*04*/ uint32 stamina;
/*08*/ uint32 spell_id;
/*12*/ uint8 keepcasting; // won't stop the cast. Change mana while casting?
/*13*/ uint8 padding[3]; // client doesn't read it, garbage data seems like
/*16*/ int32 slot; // -1 for normal usage slot for when we want silent interrupt? I think it does timer stuff or something. Linked Spell Reuse interrupt uses it
};
struct SwapSpell_Struct
@@ -694,69 +709,31 @@ struct SpawnAppearance_Struct
struct SpellBuff_Struct
{
/*000*/ uint8 slotid; // badly named... seems to be 2 for a real buff, 0 otherwise
/*001*/ float unknown004; // Seen 1 for no buff
/*005*/ uint32 player_id; // 'global' ID of the caster, for wearoff messages
/*009*/ uint32 unknown016;
/*013*/ uint8 bard_modifier;
/*014*/ int32 duration;
/*018*/ uint8 level;
/*019*/ uint32 spellid;
/*023*/ uint32 counters;
/*027*/ uint8 unknown0028[53];
/*080*/
};
struct SpellBuff_Struct_Old
{
/*000*/ uint8 slotid; // badly named... seems to be 2 for a real buff, 0 otherwise
/*001*/ uint8 level;
/*002*/ uint8 bard_modifier;
/*003*/ uint8 effect; // not real
/*004*/ float unknown004; // Seen 1 for no buff
/*008*/ uint32 spellid;
/*012*/ int32 duration;
/*016*/ uint32 unknown016;
/*020*/ uint32 player_id; // 'global' ID of the caster, for wearoff messages
/*024*/ uint32 counters;
/*028*/ uint8 unknown0028[60];
/*000*/ uint8 effect_type; // 0 = no buff, 2 = buff, 4 = inverse affects of buff
/*001*/ uint8 level; // Seen 1 for no buff
/*002*/ uint8 unknown002; //pretty sure padding now
/*003*/ uint8 unknown003; // MQ2 used to call this "damage shield" -- don't see client referencing it, so maybe server side DS type tracking?
/*004*/ float bard_modifier;
/*008*/ uint32 spellid;
/*012*/ uint32 duration;
/*016*/ uint32 player_id; // caster ID, pretty sure just zone ID
/*020*/ uint32 num_hits;
/*024*/ float y; // referenced by SPA 441
/*028*/ float x; // unsure if all buffs get them
/*032*/ float z; // as valid data
/*036*/ uint32 unknown036;
/*040*/ int32 slot_data[12]; // book keeping stuff per slot (counters, rune/vie)
/*088*/
};
// Not functional yet, but this is what the packet looks like on Live
struct SpellBuffFade_Struct_Live {
/*000*/ uint32 entityid; // Player id who cast the buff
/*004*/ uint8 unknown004;
/*005*/ uint8 level;
/*006*/ uint8 effect;
/*007*/ uint8 unknown007;
/*008*/ float unknown008;
/*012*/ uint32 spellid;
/*016*/ int32 duration;
/*020*/ uint32 playerId; // Global player ID?
/*024*/ uint32 num_hits;
/*028*/ uint8 unknown0028[64];
struct SpellBuffPacket_Struct {
/*000*/ uint32 entityid; // Player id who cast the buff
/*004*/ SpellBuff_Struct buff;
/*092*/ uint32 slotid;
/*096*/ uint32 bufffade;
/*100*/
};
struct SpellBuffFade_Struct {
/*000*/ uint32 entityid;
/*004*/ uint8 slot;
/*005*/ uint8 level;
/*006*/ uint8 effect;
/*007*/ uint8 unknown7;
/*008*/ uint32 spellid;
/*012*/ int32 duration;
/*016*/ uint32 num_hits;
/*020*/ uint32 unknown020; // Global player ID?
/*024*/ uint32 playerId; // Player id who cast the buff
/*028*/ uint32 slotid;
/*032*/ uint32 bufffade;
/*036*/
};
struct BuffRemoveRequest_Struct
{
/*00*/ uint32 SlotID;
@@ -1061,38 +1038,38 @@ union
{
struct
{
/*00184*/ EquipStruct equip_helmet; // Equiptment: Helmet visual
/*00204*/ EquipStruct equip_chest; // Equiptment: Chest visual
/*00224*/ EquipStruct equip_arms; // Equiptment: Arms visual
/*00244*/ EquipStruct equip_bracers; // Equiptment: Wrist visual
/*00264*/ EquipStruct equip_hands; // Equiptment: Hands visual
/*00284*/ EquipStruct equip_legs; // Equiptment: Legs visual
/*00304*/ EquipStruct equip_feet; // Equiptment: Boots visual
/*00324*/ EquipStruct equip_primary; // Equiptment: Main visual
/*00344*/ EquipStruct equip_secondary; // Equiptment: Off visual
/*00184*/ Texture_Struct equip_helmet; // Equiptment: Helmet visual
/*00204*/ Texture_Struct equip_chest; // Equiptment: Chest visual
/*00224*/ Texture_Struct equip_arms; // Equiptment: Arms visual
/*00244*/ Texture_Struct equip_bracers; // Equiptment: Wrist visual
/*00264*/ Texture_Struct equip_hands; // Equiptment: Hands visual
/*00284*/ Texture_Struct equip_legs; // Equiptment: Legs visual
/*00304*/ Texture_Struct equip_feet; // Equiptment: Boots visual
/*00324*/ Texture_Struct equip_primary; // Equiptment: Main visual
/*00344*/ Texture_Struct equip_secondary; // Equiptment: Off visual
// Below slots are just guesses, but all 0s anyway...
/*00364*/ EquipStruct equip_charm; // Equiptment: Non-visual
/*00384*/ EquipStruct equip_ear1; // Equiptment: Non-visual
/*00404*/ EquipStruct equip_ear2; // Equiptment: Non-visual
/*00424*/ EquipStruct equip_face; // Equiptment: Non-visual
/*00444*/ EquipStruct equip_neck; // Equiptment: Non-visual
/*00464*/ EquipStruct equip_shoulder; // Equiptment: Non-visual
/*00484*/ EquipStruct equip_bracer2; // Equiptment: Non-visual
/*00504*/ EquipStruct equip_range; // Equiptment: Non-visual
/*00524*/ EquipStruct equip_ring1; // Equiptment: Non-visual
/*00544*/ EquipStruct equip_ring2; // Equiptment: Non-visual
/*00564*/ EquipStruct equip_waist; // Equiptment: Non-visual
/*00584*/ EquipStruct equip_powersource; // Equiptment: Non-visual
/*00604*/ EquipStruct equip_ammo; // Equiptment: Non-visual
/*00364*/ Texture_Struct equip_charm; // Equiptment: Non-visual
/*00384*/ Texture_Struct equip_ear1; // Equiptment: Non-visual
/*00404*/ Texture_Struct equip_ear2; // Equiptment: Non-visual
/*00424*/ Texture_Struct equip_face; // Equiptment: Non-visual
/*00444*/ Texture_Struct equip_neck; // Equiptment: Non-visual
/*00464*/ Texture_Struct equip_shoulder; // Equiptment: Non-visual
/*00484*/ Texture_Struct equip_bracer2; // Equiptment: Non-visual
/*00504*/ Texture_Struct equip_range; // Equiptment: Non-visual
/*00524*/ Texture_Struct equip_ring1; // Equiptment: Non-visual
/*00544*/ Texture_Struct equip_ring2; // Equiptment: Non-visual
/*00564*/ Texture_Struct equip_waist; // Equiptment: Non-visual
/*00584*/ Texture_Struct equip_powersource; // Equiptment: Non-visual
/*00604*/ Texture_Struct equip_ammo; // Equiptment: Non-visual
} equip;
/*00184*/ EquipStruct equipment[22];
/*00184*/ Texture_Struct equipment[22];
};
/*00624*/ uint32 equip2_count; // Seen 9
/*00628*/ EquipStruct equipment2[9]; // Appears to be Visible slots, but all 0s
/*00628*/ Texture_Struct equipment2[9]; // Appears to be Visible slots, but all 0s
/*00808*/ uint32 tint_count; // Seen 9
/*00812*/ Color_Struct item_tint[9]; // RR GG BB 00
/*00812*/ TintProfile item_tint; // RR GG BB 00
/*00848*/ uint32 tint_count2; // Seen 9
/*00852*/ Color_Struct item_tint2[9]; // RR GG BB 00
/*00852*/ TintProfile item_tint2; // RR GG BB 00
/*00888*/ uint8 haircolor; // Player hair color
/*00889*/ uint8 beardcolor; // Player beard color
/*00890*/ uint32 unknown_rof5; //
@@ -1415,7 +1392,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*/ Color_Struct color;
/*022*/ Tint_Struct color;
/*026*/ uint8 wear_slot_id;
/*027*/
};
@@ -2473,7 +2450,7 @@ struct AdventureLeaderboard_Struct
/*struct Item_Shop_Struct {
uint16 merchantid;
uint8 itemtype;
Item_Struct item;
ItemBase item;
uint8 iss_unknown001[6];
};*/
@@ -3634,27 +3611,6 @@ struct PetitionBug_Struct{
char text[1028];
};
struct DyeStruct
{
union
{
struct
{
struct Color_Struct head;
struct Color_Struct chest;
struct Color_Struct arms;
struct Color_Struct wrists;
struct Color_Struct hands;
struct Color_Struct legs;
struct Color_Struct feet;
struct Color_Struct primary; // you can't actually dye this
struct Color_Struct secondary; // or this
}
dyes;
struct Color_Struct dye[9];
};
};
struct ApproveZone_Struct {
char name[64];
uint32 zoneid;
+117 -40
View File
@@ -59,6 +59,9 @@ namespace SoD
// client to server text link converter
static inline void SoDToServerTextLink(std::string& serverTextLink, const std::string& sodTextLink);
static inline CastingSlot ServerToSoDCastingSlot(EQEmu::CastingSlot slot);
static inline EQEmu::CastingSlot SoDToServerCastingSlot(CastingSlot slot);
void Register(EQStreamIdentifier &into)
{
//create our opcode manager if we havent already
@@ -301,16 +304,17 @@ namespace SoD
ENCODE(OP_Buff)
{
ENCODE_LENGTH_EXACT(SpellBuffFade_Struct);
SETUP_DIRECT_ENCODE(SpellBuffFade_Struct, structs::SpellBuffFade_Struct);
ENCODE_LENGTH_EXACT(SpellBuffPacket_Struct);
SETUP_DIRECT_ENCODE(SpellBuffPacket_Struct, structs::SpellBuffPacket_Struct);
OUT(entityid);
OUT(slot);
OUT(level);
OUT(effect);
//eq->unknown7 = 10;
OUT(spellid);
OUT(duration);
OUT(buff.effect_type);
OUT(buff.level);
OUT(buff.bard_modifier);
OUT(buff.spellid);
OUT(buff.duration);
OUT(buff.counters);
OUT(buff.player_id);
OUT(slotid);
OUT(bufffade);
@@ -1135,7 +1139,8 @@ namespace SoD
OUT(new_mana);
OUT(stamina);
OUT(spell_id);
eq->unknown16 = -1; // Self Interrupt/Success = -1, Fizzle = 1, Other Interrupt = 2?
OUT(keepcasting);
eq->slot = -1; // this is spell gem slot. It's -1 in normal operation
FINISH_ENCODE();
}
@@ -1498,7 +1503,7 @@ namespace SoD
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, emu->petid);
VARSTRUCT_ENCODE_TYPE(uint16, Buffer, emu->buffcount);
for (unsigned int i = 0; i < BUFF_COUNT; ++i)
for (unsigned int i = 0; i < PET_BUFF_COUNT; ++i)
{
if (emu->spellid[i])
{
@@ -1509,7 +1514,7 @@ namespace SoD
}
}
VARSTRUCT_ENCODE_TYPE(uint8, Buffer, emu->buffcount);
VARSTRUCT_ENCODE_TYPE(uint8, Buffer, emu->buffcount); // I think this is actually some sort of type
delete[] __emu_buffer;
dest->FastQueuePacket(&in, ack_req);
@@ -1553,14 +1558,14 @@ namespace SoD
OUT(hairstyle);
OUT(beard);
// OUT(unknown00178[10]);
for (r = 0; r < 9; r++) {
eq->equipment[r].Material = emu->item_material[r];
eq->equipment[r].Unknown1 = 0;
eq->equipment[r].EliteMaterial = 0;
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;
//eq->colors[r].color = emu->colors[r].color;
}
for (r = 0; r < 7; r++) {
OUT(item_tint[r].Color);
OUT(item_tint.Slot[r].Color);
}
// OUT(unknown00224[48]);
//NOTE: new client supports 300 AAs, our internal rep/PP
@@ -1602,10 +1607,10 @@ namespace SoD
OUT(thirst_level);
OUT(hunger_level);
for (r = 0; r < structs::BUFF_COUNT; r++) {
OUT(buffs[r].slotid);
OUT(buffs[r].effect_type);
OUT(buffs[r].level);
OUT(buffs[r].bard_modifier);
OUT(buffs[r].effect);
OUT(buffs[r].unknown003);
OUT(buffs[r].spellid);
OUT(buffs[r].duration);
OUT(buffs[r].counters);
@@ -1993,11 +1998,11 @@ namespace SoD
eq_cse->HairColor = emu_cse->HairColor;
eq_cse->Face = emu_cse->Face;
for (int equip_index = 0; equip_index < EQEmu::legacy::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].EliteMaterial;
eq_cse->Equip[equip_index].Color.Color = emu_cse->Equip[equip_index].Color.Color;
eq_cse->Equip[equip_index].Color = emu_cse->Equip[equip_index].Color;
}
eq_cse->PrimaryIDFile = emu_cse->PrimaryIDFile;
@@ -2563,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::EquipStruct) * 9);
PacketSize -= (sizeof(structs::Texture_Struct) * EQEmu::textures::TextureCount);
if (emu->size == 0)
{
@@ -2760,10 +2765,10 @@ namespace SoD
if ((emu->NPC == 0) || (emu->race <= 12) || (emu->race == 128) || (emu->race == 130) || (emu->race == 330) || (emu->race == 522))
{
for (k = 0; k < 9; ++k)
for (k = EQEmu::textures::TextureBegin; k < EQEmu::textures::TextureCount; ++k)
{
{
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, emu->colors[k].Color);
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, emu->equipment_tint.Slot[k].Color);
}
}
}
@@ -2773,11 +2778,11 @@ namespace SoD
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0);
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0);
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, emu->equipment[EQEmu::legacy::MaterialPrimary].Material);
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, emu->equipment.Primary.Material);
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0);
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0);
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, emu->equipment[EQEmu::legacy::MaterialSecondary].Material);
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, emu->equipment.Secondary.Material);
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0);
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0);
}
@@ -2785,15 +2790,15 @@ namespace SoD
if ((emu->NPC == 0) || (emu->race <= 12) || (emu->race == 128) || (emu->race == 130) || (emu->race == 330) || (emu->race == 522))
{
structs::EquipStruct *Equipment = (structs::EquipStruct *)Buffer;
structs::Texture_Struct *Equipment = (structs::Texture_Struct *)Buffer;
for (k = 0; k < 9; k++) {
Equipment[k].Material = emu->equipment[k].Material;
Equipment[k].Unknown1 = emu->equipment[k].Unknown1;
Equipment[k].EliteMaterial = emu->equipment[k].EliteMaterial;
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].EliteMaterial;
}
Buffer += (sizeof(structs::EquipStruct) * 9);
Buffer += (sizeof(structs::Texture_Struct) * EQEmu::textures::TextureCount);
}
if (strlen(emu->title))
{
@@ -2907,15 +2912,16 @@ namespace SoD
DECODE(OP_Buff)
{
DECODE_LENGTH_EXACT(structs::SpellBuffFade_Struct);
SETUP_DIRECT_DECODE(SpellBuffFade_Struct, structs::SpellBuffFade_Struct);
DECODE_LENGTH_EXACT(structs::SpellBuffPacket_Struct);
SETUP_DIRECT_DECODE(SpellBuffPacket_Struct, structs::SpellBuffPacket_Struct);
IN(entityid);
IN(slot);
IN(level);
IN(effect);
IN(spellid);
IN(duration);
IN(buff.effect_type);
IN(buff.level);
IN(buff.bard_modifier);
IN(buff.spellid);
IN(buff.duration);
IN(buff.counters)
IN(slotid);
IN(bufffade);
@@ -2946,6 +2952,7 @@ namespace SoD
DECODE_LENGTH_EXACT(structs::CastSpell_Struct);
SETUP_DIRECT_DECODE(CastSpell_Struct, structs::CastSpell_Struct);
emu->slot = static_cast<uint32>(SoDToServerCastingSlot(static_cast<CastingSlot>(eq->slot)));
IN(slot);
IN(spell_id);
emu->inventoryslot = SoDToServerSlot(eq->inventoryslot);
@@ -3239,8 +3246,10 @@ namespace SoD
DECODE_LENGTH_EXACT(structs::LoadSpellSet_Struct);
SETUP_DIRECT_DECODE(LoadSpellSet_Struct, structs::LoadSpellSet_Struct);
for (uint32 i = 0; i < MAX_PP_MEMSPELL; ++i)
for (int i = 0; i < structs::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();
}
@@ -3546,7 +3555,7 @@ namespace SoD
void SerializeItem(EQEmu::OutBuffer& ob, const ItemInst *inst, int16 slot_id_in, uint8 depth)
{
const EQEmu::Item_Struct *item = inst->GetUnscaledItem();
const EQEmu::ItemBase *item = inst->GetUnscaledItem();
SoD::structs::ItemSerializationHeader hdr;
@@ -4011,4 +4020,72 @@ namespace SoD
}
}
static inline CastingSlot ServerToSoDCastingSlot(EQEmu::CastingSlot slot)
{
switch (slot) {
case EQEmu::CastingSlot::Gem1:
return CastingSlot::Gem1;
case EQEmu::CastingSlot::Gem2:
return CastingSlot::Gem2;
case EQEmu::CastingSlot::Gem3:
return CastingSlot::Gem3;
case EQEmu::CastingSlot::Gem4:
return CastingSlot::Gem4;
case EQEmu::CastingSlot::Gem5:
return CastingSlot::Gem5;
case EQEmu::CastingSlot::Gem6:
return CastingSlot::Gem6;
case EQEmu::CastingSlot::Gem7:
return CastingSlot::Gem7;
case EQEmu::CastingSlot::Gem8:
return CastingSlot::Gem8;
case EQEmu::CastingSlot::Gem9:
return CastingSlot::Gem9;
case EQEmu::CastingSlot::Gem10:
return CastingSlot::Gem10;
case EQEmu::CastingSlot::Item:
case EQEmu::CastingSlot::PotionBelt:
return CastingSlot::Item;
case EQEmu::CastingSlot::Discipline:
return CastingSlot::Discipline;
case EQEmu::CastingSlot::AltAbility:
return CastingSlot::AltAbility;
default: // we shouldn't have any issues with other slots ... just return something
return CastingSlot::Discipline;
}
}
static inline EQEmu::CastingSlot SoDToServerCastingSlot(CastingSlot slot)
{
switch (slot) {
case CastingSlot::Gem1:
return EQEmu::CastingSlot::Gem1;
case CastingSlot::Gem2:
return EQEmu::CastingSlot::Gem2;
case CastingSlot::Gem3:
return EQEmu::CastingSlot::Gem3;
case CastingSlot::Gem4:
return EQEmu::CastingSlot::Gem4;
case CastingSlot::Gem5:
return EQEmu::CastingSlot::Gem5;
case CastingSlot::Gem6:
return EQEmu::CastingSlot::Gem6;
case CastingSlot::Gem7:
return EQEmu::CastingSlot::Gem7;
case CastingSlot::Gem8:
return EQEmu::CastingSlot::Gem8;
case CastingSlot::Gem9:
return EQEmu::CastingSlot::Gem9;
case CastingSlot::Gem10:
return EQEmu::CastingSlot::Gem10;
case CastingSlot::Discipline:
return EQEmu::CastingSlot::Discipline;
case CastingSlot::Item:
return EQEmu::CastingSlot::Item;
case CastingSlot::AltAbility:
return EQEmu::CastingSlot::AltAbility;
default: // we shouldn't have any issues with other slots ... just return something
return EQEmu::CastingSlot::Discipline;
}
}
} /*SoD*/
+16
View File
@@ -50,6 +50,22 @@ namespace SoD
#include "sod_ops.h"
};
enum class CastingSlot : uint32 {
Gem1 = 0,
Gem2 = 1,
Gem3 = 2,
Gem4 = 3,
Gem5 = 4,
Gem6 = 5,
Gem7 = 6,
Gem8 = 7,
Gem9 = 8,
Gem10 = 9,
Item = 10,
Discipline = 11,
AltAbility = 0xFF
};
}; /*SoD*/
#endif /*COMMON_SOD_H*/
+29 -12
View File
@@ -10,7 +10,7 @@
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.
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
@@ -22,7 +22,7 @@
#include "../string_util.h"
size_t SoD::invtype::InvTypeSize(int inv_type)
size_t SoD::invtype::GetInvTypeSize(int inv_type)
{
switch (inv_type) {
case invtype::InvTypePossessions:
@@ -68,7 +68,7 @@ size_t SoD::invtype::InvTypeSize(int inv_type)
}
}
const char* SoD::invtype::InvTypeName(int inv_type)
const char* SoD::invtype::GetInvTypeName(int inv_type)
{
switch (inv_type) {
case invtype::InvTypeInvalid:
@@ -116,7 +116,24 @@ const char* SoD::invtype::InvTypeName(int inv_type)
}
}
const char* SoD::invslot::InvPossessionsSlotName(int inv_slot)
bool SoD::invtype::IsInvTypePersistent(int inv_type)
{
switch (inv_type) {
case invtype::InvTypePossessions:
case invtype::InvTypeBank:
case invtype::InvTypeSharedBank:
case invtype::InvTypeTrade:
case invtype::InvTypeWorld:
case invtype::InvTypeLimbo:
case invtype::InvTypeTribute:
case invtype::InvTypeGuildTribute:
return true;
default:
return false;
}
}
const char* SoD::invslot::GetInvPossessionsSlotName(int inv_slot)
{
switch (inv_slot) {
case invslot::InvSlotInvalid:
@@ -190,9 +207,9 @@ const char* SoD::invslot::InvPossessionsSlotName(int inv_slot)
}
}
const char* SoD::invslot::InvCorpseSlotName(int inv_slot)
const char* SoD::invslot::GetInvCorpseSlotName(int inv_slot)
{
if (!invtype::InvTypeSize(invtype::InvTypeCorpse) || inv_slot == invslot::InvSlotInvalid)
if (!invtype::GetInvTypeSize(invtype::InvTypeCorpse) || inv_slot == invslot::InvSlotInvalid)
return "Invalid Slot";
// needs work
@@ -205,14 +222,14 @@ const char* SoD::invslot::InvCorpseSlotName(int inv_slot)
return ret_str.c_str();
}
const char* SoD::invslot::InvSlotName(int inv_type, int inv_slot)
const char* SoD::invslot::GetInvSlotName(int inv_type, int inv_slot)
{
if (inv_type == invtype::InvTypePossessions)
return invslot::InvPossessionsSlotName(inv_slot);
return invslot::GetInvPossessionsSlotName(inv_slot);
else if (inv_type == invtype::InvTypeCorpse)
return invslot::InvCorpseSlotName(inv_slot);
return invslot::GetInvCorpseSlotName(inv_slot);
size_t type_size = invtype::InvTypeSize(inv_type);
size_t type_size = invtype::GetInvTypeSize(inv_type);
if (!type_size || inv_slot == invslot::InvSlotInvalid)
return "Invalid Slot";
@@ -226,7 +243,7 @@ const char* SoD::invslot::InvSlotName(int inv_type, int inv_slot)
return ret_str.c_str();
}
const char* SoD::invbag::InvBagIndexName(int bag_index)
const char* SoD::invbag::GetInvBagIndexName(int bag_index)
{
if (bag_index == invbag::InvBagInvalid)
return "Invalid Bag";
@@ -240,7 +257,7 @@ const char* SoD::invbag::InvBagIndexName(int bag_index)
return ret_str.c_str();
}
const char* SoD::invaug::InvAugIndexName(int aug_index)
const char* SoD::invaug::GetInvAugIndexName(int aug_index)
{
if (aug_index == invaug::InvAugInvalid)
return "Invalid Augment";
+40 -28
View File
@@ -10,7 +10,7 @@
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.
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
@@ -21,7 +21,7 @@
#define COMMON_SOD_LIMITS_H
#include "../types.h"
#include "../client_version.h"
#include "../emu_versions.h"
#include "../skills.h"
@@ -32,8 +32,13 @@ namespace SoD
enum : bool { False = false, True = true };
// pre-declarations
namespace inventory {
inline EQEmu::versions::ClientVersion GetInventoryRef() { return EQEmu::versions::ClientVersion::SoD; }
} /*inventory*/
namespace invtype {
inline EQEmu::versions::ClientVersion InvTypeRef() { return EQEmu::versions::ClientVersion::SoD; }
inline EQEmu::versions::ClientVersion GetInvTypeRef() { return EQEmu::versions::ClientVersion::SoD; }
enum : int { InvTypeInvalid = -1, InvTypeBegin };
@@ -63,7 +68,7 @@ namespace SoD
} /*invtype*/
namespace invslot {
inline EQEmu::versions::ClientVersion InvSlotRef() { return EQEmu::versions::ClientVersion::SoD; }
inline EQEmu::versions::ClientVersion GetInvSlotRef() { return EQEmu::versions::ClientVersion::SoD; }
enum : int { InvSlotInvalid = -1, InvSlotBegin };
@@ -114,21 +119,21 @@ namespace SoD
} /*invslot*/
namespace invbag {
inline EQEmu::versions::ClientVersion InvBagRef() { return EQEmu::versions::ClientVersion::SoD; }
inline EQEmu::versions::ClientVersion GetInvBagRef() { return EQEmu::versions::ClientVersion::SoD; }
enum : int { InvBagInvalid = -1, InvBagBegin };
} /*invbag*/
namespace invaug {
inline EQEmu::versions::ClientVersion InvAugRef() { return EQEmu::versions::ClientVersion::SoD; }
inline EQEmu::versions::ClientVersion GetInvAugRef() { return EQEmu::versions::ClientVersion::SoD; }
enum : int { InvAugInvalid = -1, InvAugBegin };
} /*invaug*/
namespace item {
inline EQEmu::versions::ClientVersion ItemRef() { return EQEmu::versions::ClientVersion::SoD; }
inline EQEmu::versions::ClientVersion GetItemRef() { return EQEmu::versions::ClientVersion::SoD; }
enum ItemPacketType : int {
ItemPacketMerchant = 100,
@@ -146,27 +151,37 @@ namespace SoD
} /*item*/
namespace profile {
inline EQEmu::versions::ClientVersion ProfileRef() { return EQEmu::versions::ClientVersion::SoD; }
inline EQEmu::versions::ClientVersion GetProfileRef() { return EQEmu::versions::ClientVersion::SoD; }
} /*profile*/
namespace constants {
inline EQEmu::versions::ClientVersion ConstantsRef() { return EQEmu::versions::ClientVersion::SoD; }
inline EQEmu::versions::ClientVersion GetConstantsRef() { return EQEmu::versions::ClientVersion::SoD; }
} /*constants*/
namespace behavior {
inline EQEmu::versions::ClientVersion BehaviorRef() { return EQEmu::versions::ClientVersion::SoD; }
inline EQEmu::versions::ClientVersion GetBehaviorRef() { return EQEmu::versions::ClientVersion::SoD; }
} /*behavior*/
namespace skills {
inline EQEmu::versions::ClientVersion SkillsRef() { return EQEmu::versions::ClientVersion::SoD; }
inline EQEmu::versions::ClientVersion GetSkillsRef() { return EQEmu::versions::ClientVersion::SoD; }
} /*skills*/
// declarations
namespace inventory {
const bool ConcatenateInvTypeLimbo = true;
const bool AllowOverLevelEquipment = false;
const bool AllowEmptyBagInBag = false;
const bool AllowClickCastFromBag = false;
} /*inventory*/
namespace invtype {
const size_t InvTypePossessionsSize = invslot::PossessionsCount;
const size_t InvTypeBankSize = 24;
@@ -175,7 +190,7 @@ namespace SoD
const size_t InvTypeWorldSize = 10;
const size_t InvTypeLimboSize = 36;
const size_t InvTypeTributeSize = 5;
const size_t InvTypeGuildTributeSize = 0;//unknown
const size_t InvTypeGuildTributeSize = 2;
const size_t InvTypeMerchantSize = 80;
const size_t InvTypeCorpseSize = InvTypePossessionsSize;
const size_t InvTypeBazaarSize = 80;
@@ -188,10 +203,10 @@ namespace SoD
const size_t InvTypeArchivedSize = 0;//unknown
const size_t InvTypeOtherSize = 0;//unknown
const size_t NPCTradeSize = 4;
extern size_t GetInvTypeSize(int inv_type);
extern const char* GetInvTypeName(int inv_type);
extern size_t InvTypeSize(int inv_type);
extern const char* InvTypeName(int inv_type);
extern bool IsInvTypePersistent(int inv_type);
} /*invtype*/
@@ -210,14 +225,17 @@ namespace SoD
const int WorldEnd = (WorldBegin + invtype::InvTypeWorldSize) - 1;
const int TributeBegin = 400;
const int TributeEnd = 404;
const int TributeEnd = (TributeBegin + invtype::InvTypeTributeSize) - 1;
const int GuildTributeBegin = 450;
const int GuildTributeEnd = (GuildTributeBegin + invtype::InvTypeGuildTributeSize) - 1;
const int CorpseBegin = invslot::PossessionsGeneral1;
const int CorpseEnd = invslot::PossessionsGeneral1 + invslot::PossessionsCursor;
extern const char* InvPossessionsSlotName(int inv_slot);
extern const char* InvCorpseSlotName(int inv_slot);
extern const char* InvSlotName(int inv_type, int inv_slot);
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*/
@@ -244,14 +262,14 @@ namespace SoD
const int TradeBagsSize = invtype::InvTypeTradeSize * ItemBagSize;
const int TradeBagsEnd = (TradeBagsBegin + TradeBagsSize) - 1;
extern const char* InvBagIndexName(int bag_index);
extern const char* GetInvBagIndexName(int bag_index);
} /*invbag*/
namespace invaug {
const size_t ItemAugSize = 5;
extern const char* InvAugIndexName(int aug_index);
extern const char* GetInvAugIndexName(int aug_index);
} /*invaug*/
@@ -261,6 +279,7 @@ namespace SoD
namespace profile {
const size_t TributeSize = invtype::InvTypeTributeSize;
const size_t GuildTributeSize = invtype::InvTypeGuildTributeSize;
const size_t BandoliersSize = 20; // number of bandolier instances
const size_t BandolierItemCount = 4; // number of equipment slots in bandolier instance
@@ -279,13 +298,6 @@ namespace SoD
} /*constants*/
namespace behavior {
const bool ConcatenateInvTypeLimbo = true;
const bool AllowOverLevelEquipment = false;
const bool AllowEmptyBagInBag = false;
const bool AllowClickCastFromBag = false;
const bool CoinHasWeight = false;
} /*behavior*/
+73 -119
View File
@@ -122,7 +122,7 @@ struct AdventureInfo {
** Merth: Gave struct a name so gcc 2.96 would compile
**
*/
struct Color_Struct
struct Tint_Struct
{
union {
struct {
@@ -130,19 +130,62 @@ struct Color_Struct
uint8 Green;
uint8 Red;
uint8 UseTint; // if there's a tint this is FF
} RGB;
};
uint32 Color;
};
};
struct CharSelectEquip
struct TintProfile
{
union {
struct {
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;
};
Tint_Struct Slot[EQEmu::textures::TextureCount];
};
};
/*
* Visible equiptment.
* Size: 12 Octets
*/
struct Texture_Struct
{
uint32 Material;
uint32 Unknown1;
uint32 EliteMaterial;
Color_Struct Color;
};
struct TextureProfile
{
union {
struct {
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;
};
Texture_Struct Slot[EQEmu::textures::TextureCount];
};
TextureProfile();
};
struct CharSelectEquip : Texture_Struct, Tint_Struct {};
struct CharacterSelectEntry_Struct
{
/*0000*/ uint8 Level; //
@@ -152,7 +195,7 @@ struct CharacterSelectEntry_Struct
/*0000*/ uint8 Beard; //
/*0001*/ uint8 HairColor; //
/*0000*/ uint8 Face; //
/*0000*/ CharSelectEquip Equip[9];
/*0000*/ CharSelectEquip Equip[EQEmu::textures::TextureCount];
/*0000*/ uint32 PrimaryIDFile; //
/*0000*/ uint32 SecondaryIDFile; //
/*0000*/ uint8 Unknown15; // 0xff
@@ -185,19 +228,6 @@ struct CharacterSelect_Struct
/*0008*/ CharacterSelectEntry_Struct Entries[0];
};
/*
* Visible equiptment.
* Size: 12 Octets
*/
struct EquipStruct
{
/*00*/ uint32 Material;
/*04*/ uint32 Unknown1;
/*08*/ uint32 EliteMaterial;
/*12*/
};
/*
** Generic Spawn Struct
** Length: 897 Octets
@@ -314,40 +344,10 @@ struct Spawn_Struct
/*0000*/ uint32 unknown18;
/*0000*/ uint32 unknown19;
Spawn_Struct_Position Position;
/*0000*/ union
{
struct
{
/*0000*/ Color_Struct color_helmet; // Color of helmet item
/*0000*/ Color_Struct color_chest; // Color of chest item
/*0000*/ Color_Struct color_arms; // Color of arms item
/*0000*/ Color_Struct color_bracers; // Color of bracers item
/*0000*/ Color_Struct color_hands; // Color of hands item
/*0000*/ Color_Struct color_legs; // Color of legs item
/*0000*/ Color_Struct color_feet; // Color of feet item
/*0000*/ Color_Struct color_primary; // Color of primary item
/*0000*/ Color_Struct color_secondary; // Color of secondary item
} equipment_colors;
/*0000*/ Color_Struct colors[9]; // Array elements correspond to struct equipment_colors above
};
/*0000*/ TintProfile equipment_tint;
// skip these bytes if not a valid player race
/*0000*/ union
{
struct
{
/*0000*/ EquipStruct equip_helmet; // Equiptment: Helmet visual
/*0000*/ EquipStruct equip_chest; // Equiptment: Chest visual
/*0000*/ EquipStruct equip_arms; // Equiptment: Arms visual
/*0000*/ EquipStruct equip_bracers; // Equiptment: Wrist visual
/*0000*/ EquipStruct equip_hands; // Equiptment: Hands visual
/*0000*/ EquipStruct equip_legs; // Equiptment: Legs visual
/*0000*/ EquipStruct equip_feet; // Equiptment: Boots visual
/*0000*/ EquipStruct equip_primary; // Equiptment: Main visual
/*0000*/ EquipStruct equip_secondary; // Equiptment: Off visual
} equip;
/*0000*/ EquipStruct equipment[9];
};
/*0000*/ TextureProfile equipment;
/*0000*/ //char title[0]; // only read if(hasTitleOrSuffix & 4)
/*0000*/ //char suffix[0]; // only read if(hasTitleOrSuffix & 8)
@@ -479,7 +479,7 @@ struct MemorizeSpell_Struct {
uint32 slot; // Spot in the spell book/memorized slot
uint32 spell_id; // Spell id (200 or c8 is minor healing, etc)
uint32 scribing; // 1 if memorizing a spell, set to 0 if scribing to book, 2 if un-memming
//uint32 unknown12;
uint32 reduction; // lowers reuse
};
/*
@@ -512,11 +512,12 @@ struct DeleteSpell_Struct
struct ManaChange_Struct
{
uint32 new_mana; // New Mana AMount
uint32 stamina;
uint32 spell_id;
uint32 unknown12;
uint32 unknown16;
/*00*/ uint32 new_mana; // New Mana AMount
/*04*/ uint32 stamina;
/*08*/ uint32 spell_id;
/*12*/ uint8 keepcasting; // won't stop the cast. Change mana while casting?
/*13*/ uint8 padding[3]; // client doesn't read it, garbage data seems like
/*16*/ int32 slot; // -1 for normal usage slot for when we want silent interrupt? I think it does timer stuff or something. Linked Spell Reuse interrupt uses it
};
struct SwapSpell_Struct
@@ -563,32 +564,22 @@ struct SpawnAppearance_Struct
// this is used inside profile
struct SpellBuff_Struct
{
/*000*/ uint8 slotid; //badly named... seems to be 2 for a real buff, 0 otherwise
/*001*/ uint8 level;
/*002*/ uint8 bard_modifier;
/*003*/ uint8 effect; //not real
/*004*/ uint32 spellid;
/*008*/ int32 duration;
/*012*/ uint32 counters;
/*016*/ uint32 unknown004; //Might need to be swapped with player_id
/*020*/ uint32 player_id; //'global' ID of the caster, for wearoff messages
/*000*/ uint8 effect_type; // 0 = no buff, 2 = buff, 4 = inverse affects of buff
/*001*/ uint8 level; // Seen 1 for no buff
/*002*/ uint8 bard_modifier;
/*003*/ uint8 unknown003; // MQ2 used to call this "damage shield" -- don't see client referencing it, so maybe server side DS type tracking?
/*004*/ uint32 spellid;
/*008*/ uint32 duration;
/*012*/ uint32 counters;
/*016*/ uint32 unknown016;
/*020*/ uint32 player_id; // caster ID, pretty sure just zone ID
/*024*/
};
struct SpellBuffFade_Struct {
struct SpellBuffPacket_Struct {
/*000*/ uint32 entityid;
/*004*/ uint8 slot;
/*005*/ uint8 level;
/*006*/ uint8 effect;
/*007*/ uint8 unknown7;
/*008*/ uint32 spellid;
/*012*/ int32 duration;
/*016*/ uint32 unknown016;
/*020*/ uint32 unknown020; //prolly global player ID
/*024*/ uint32 playerId; // Player id who cast the buff
/*004*/ SpellBuff_Struct buff;
/*028*/ uint32 slotid;
/*032*/ uint32 bufffade;
/*036*/
@@ -903,24 +894,9 @@ struct PlayerProfile_Struct
/*00216*/ uint8 hairstyle; // Player hair style
/*00217*/ uint8 beard; // Player beard type
/*00218*/ uint8 unknown00178[14]; //[10]14 on Live? was 10
/*00232*/ union
{
struct
{
/*00228*/ EquipStruct equip_helmet; // Equiptment: Helmet visual
/*00240*/ EquipStruct equip_chest; // Equiptment: Chest visual
/*00252*/ EquipStruct equip_arms; // Equiptment: Arms visual
/*00264*/ EquipStruct equip_bracers; // Equiptment: Wrist visual
/*00276*/ EquipStruct equip_hands; // Equiptment: Hands visual
/*00288*/ EquipStruct equip_legs; // Equiptment: Legs visual
/*00300*/ EquipStruct equip_feet; // Equiptment: Boots visual
/*00312*/ EquipStruct equip_primary; // Equiptment: Main visual
/*00324*/ EquipStruct equip_secondary; // Equiptment: Off visual
} equip;
/*00228*/ EquipStruct equipment[9]; //Live Shows [108] for this part
};
/*00232*/ TextureProfile equipment;
/*00340*/ uint8 unknown00224[156]; // Live Shows [160]
/*00496*/ Color_Struct item_tint[9]; // RR GG BB 00
/*00496*/ TintProfile item_tint; // RR GG BB 00
/*00532*/ AA_Array aa_array[MAX_PP_AA_ARRAY]; // [3600] AAs 12 bytes each
/*04132*/ uint32 points; // Unspent Practice points - RELOCATED???
/*04136*/ uint32 mana; // Current mana
@@ -1177,7 +1153,7 @@ struct WearChange_Struct{
/*002*/ uint32 material;
/*006*/ uint32 unknown06;
/*010*/ uint32 elite_material; // 1 for Drakkin Elite Material
/*014*/ Color_Struct color;
/*014*/ Tint_Struct color;
/*018*/ uint8 wear_slot_id;
/*019*/
};
@@ -1904,8 +1880,7 @@ struct Merchant_Sell_Struct {
/*004*/ uint32 playerid; // Player's entity id
/*008*/ uint32 itemslot;
/*012*/ uint32 unknown12;
/*016*/ uint8 quantity; // Already sold
/*017*/ uint8 Unknown017[3];
/*016*/ uint32 quantity;
/*020*/ uint32 Unknown020;
/*024*/ uint32 price;
/*028*/ uint32 pricehighorderbits; // It appears the price is 64 bits in SoD+
@@ -1995,7 +1970,7 @@ struct AdventureLeaderboard_Struct
/*struct Item_Shop_Struct {
uint16 merchantid;
uint8 itemtype;
Item_Struct item;
ItemBase item;
uint8 iss_unknown001[6];
};*/
@@ -3091,27 +3066,6 @@ struct PetitionBug_Struct{
char text[1028];
};
struct DyeStruct
{
union
{
struct
{
struct Color_Struct head;
struct Color_Struct chest;
struct Color_Struct arms;
struct Color_Struct wrists;
struct Color_Struct hands;
struct Color_Struct legs;
struct Color_Struct feet;
struct Color_Struct primary; // you can't actually dye this
struct Color_Struct secondary; // or this
}
dyes;
struct Color_Struct dye[9];
};
};
struct ApproveZone_Struct {
char name[64];
uint32 zoneid;
+145 -36
View File
@@ -59,6 +59,9 @@ namespace SoF
// client to server text link converter
static inline void SoFToServerTextLink(std::string& serverTextLink, const std::string& sofTextLink);
static inline CastingSlot ServerToSoFCastingSlot(EQEmu::CastingSlot slot);
static inline EQEmu::CastingSlot SoFToServerCastingSlot(CastingSlot slot, uint32 itemlocation);
void Register(EQStreamIdentifier &into)
{
//create our opcode manager if we havent already
@@ -283,16 +286,17 @@ namespace SoF
ENCODE(OP_Buff)
{
ENCODE_LENGTH_EXACT(SpellBuffFade_Struct);
SETUP_DIRECT_ENCODE(SpellBuffFade_Struct, structs::SpellBuffFade_Struct);
ENCODE_LENGTH_EXACT(SpellBuffPacket_Struct);
SETUP_DIRECT_ENCODE(SpellBuffPacket_Struct, structs::SpellBuffPacket_Struct);
OUT(entityid);
OUT(slot);
OUT(level);
OUT(effect);
//eq->unknown7 = 10;
OUT(spellid);
OUT(duration);
OUT(buff.effect_type);
OUT(buff.level);
OUT(buff.bard_modifier);
OUT(buff.spellid);
OUT(buff.duration);
OUT(buff.counters);
OUT(buff.player_id);
OUT(slotid);
OUT(bufffade);
@@ -932,7 +936,24 @@ namespace SoF
OUT(new_mana);
OUT(stamina);
OUT(spell_id);
eq->unknown16 = -1; // Self Interrupt/Success = -1, Fizzle = 1, Other Interrupt = 2?
OUT(keepcasting);
eq->slot = -1; // this is spell gem slot. It's -1 in normal operation
FINISH_ENCODE();
}
ENCODE(OP_MemorizeSpell)
{
ENCODE_LENGTH_EXACT(MemorizeSpell_Struct);
SETUP_DIRECT_ENCODE(MemorizeSpell_Struct, structs::MemorizeSpell_Struct);
// Since HT/LoH are translated up, we need to translate down only for memSpellSpellbar case
if (emu->scribing == 3)
eq->slot = static_cast<uint32>(ServerToSoFCastingSlot(static_cast<EQEmu::CastingSlot>(emu->slot)));
else
OUT(slot);
OUT(spell_id);
OUT(scribing);
FINISH_ENCODE();
}
@@ -1157,9 +1178,9 @@ namespace SoF
OUT(petid);
OUT(buffcount);
int EQBuffSlot = 0;
int EQBuffSlot = 0; // do we really want to shuffle them around like this?
for (uint32 EmuBuffSlot = 0; EmuBuffSlot < BUFF_COUNT; ++EmuBuffSlot)
for (uint32 EmuBuffSlot = 0; EmuBuffSlot < PET_BUFF_COUNT; ++EmuBuffSlot)
{
if (emu->spellid[EmuBuffSlot])
{
@@ -1209,14 +1230,14 @@ namespace SoF
OUT(hairstyle);
OUT(beard);
// OUT(unknown00178[10]);
for (r = 0; r < 9; r++) {
eq->equipment[r].Material = emu->item_material[r];
eq->equipment[r].Unknown1 = 0;
eq->equipment[r].EliteMaterial = 0;
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;
//eq->colors[r].color = emu->colors[r].color;
}
for (r = 0; r < 7; r++) {
OUT(item_tint[r].Color);
OUT(item_tint.Slot[r].Color);
}
// OUT(unknown00224[48]);
//NOTE: new client supports 300 AAs, our internal rep/PP
@@ -1258,10 +1279,10 @@ namespace SoF
OUT(thirst_level);
OUT(hunger_level);
for (r = 0; r < structs::BUFF_COUNT; r++) {
OUT(buffs[r].slotid);
OUT(buffs[r].effect_type);
OUT(buffs[r].level);
OUT(buffs[r].bard_modifier);
OUT(buffs[r].effect);
OUT(buffs[r].unknown003);
OUT(buffs[r].spellid);
OUT(buffs[r].duration);
OUT(buffs[r].counters);
@@ -1649,11 +1670,11 @@ namespace SoF
eq_cse->HairColor = emu_cse->HairColor;
eq_cse->Face = emu_cse->Face;
for (int equip_index = 0; equip_index < EQEmu::legacy::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].EliteMaterial;
eq_cse->Equip[equip_index].Color.Color = emu_cse->Equip[equip_index].Color.Color;
eq_cse->Equip[equip_index].Color = emu_cse->Equip[equip_index].Color;
}
eq_cse->PrimaryIDFile = emu_cse->PrimaryIDFile;
@@ -2080,11 +2101,11 @@ namespace SoF
eq->deity = emu->deity;
eq->drakkin_heritage = emu->drakkin_heritage;
eq->gender = emu->gender;
for (k = 0; k < 9; k++) {
eq->equipment[k].Material = emu->equipment[k].Material;
eq->equipment[k].Unknown1 = emu->equipment[k].Unknown1;
eq->equipment[k].EliteMaterial = emu->equipment[k].EliteMaterial;
eq->colors[k].Color = emu->colors[k].Color;
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].EliteMaterial;
eq->equipment_tint.Slot[k].Color = emu->equipment_tint.Slot[k].Color;
}
eq->StandState = emu->StandState;
eq->guildID = emu->guildID;
@@ -2146,8 +2167,8 @@ 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 = 0; k < 9; k++) {
eq->colors[k].Color = emu->colors[k].Color;
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;
eq->face = emu->face;
@@ -2343,15 +2364,17 @@ namespace SoF
DECODE(OP_Buff)
{
DECODE_LENGTH_EXACT(structs::SpellBuffFade_Struct);
SETUP_DIRECT_DECODE(SpellBuffFade_Struct, structs::SpellBuffFade_Struct);
DECODE_LENGTH_EXACT(structs::SpellBuffPacket_Struct);
SETUP_DIRECT_DECODE(SpellBuffPacket_Struct, structs::SpellBuffPacket_Struct);
IN(entityid);
IN(slot);
IN(level);
IN(effect);
IN(spellid);
IN(duration);
IN(buff.effect_type);
IN(buff.level);
IN(buff.bard_modifier);
IN(buff.spellid);
IN(buff.duration);
IN(buff.counters);
IN(buff.player_id);
IN(slotid);
IN(bufffade);
@@ -2363,7 +2386,7 @@ namespace SoF
DECODE_LENGTH_EXACT(structs::CastSpell_Struct);
SETUP_DIRECT_DECODE(CastSpell_Struct, structs::CastSpell_Struct);
IN(slot);
emu->slot = static_cast<uint32>(SoFToServerCastingSlot(static_cast<CastingSlot>(eq->slot), eq->inventoryslot));
IN(spell_id);
emu->inventoryslot = SoFToServerSlot(eq->inventoryslot);
IN(target_id);
@@ -2600,6 +2623,21 @@ 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);
@@ -2887,7 +2925,7 @@ namespace SoF
void SerializeItem(EQEmu::OutBuffer& ob, const ItemInst *inst, int16 slot_id_in, uint8 depth)
{
const EQEmu::Item_Struct *item = inst->GetUnscaledItem();
const EQEmu::ItemBase *item = inst->GetUnscaledItem();
SoF::structs::ItemSerializationHeader hdr;
@@ -3352,4 +3390,75 @@ namespace SoF
}
}
static inline CastingSlot ServerToSoFCastingSlot(EQEmu::CastingSlot slot)
{
switch (slot) {
case EQEmu::CastingSlot::Gem1:
return CastingSlot::Gem1;
case EQEmu::CastingSlot::Gem2:
return CastingSlot::Gem2;
case EQEmu::CastingSlot::Gem3:
return CastingSlot::Gem3;
case EQEmu::CastingSlot::Gem4:
return CastingSlot::Gem4;
case EQEmu::CastingSlot::Gem5:
return CastingSlot::Gem5;
case EQEmu::CastingSlot::Gem6:
return CastingSlot::Gem6;
case EQEmu::CastingSlot::Gem7:
return CastingSlot::Gem7;
case EQEmu::CastingSlot::Gem8:
return CastingSlot::Gem8;
case EQEmu::CastingSlot::Gem9:
return CastingSlot::Gem9;
case EQEmu::CastingSlot::Item:
return CastingSlot::Item;
case EQEmu::CastingSlot::PotionBelt:
return CastingSlot::PotionBelt;
case EQEmu::CastingSlot::Discipline:
return CastingSlot::Discipline;
case EQEmu::CastingSlot::AltAbility:
return CastingSlot::AltAbility;
default: // we shouldn't have any issues with other slots ... just return something
return CastingSlot::Discipline;
}
}
static inline EQEmu::CastingSlot SoFToServerCastingSlot(CastingSlot slot, uint32 itemlocation)
{
switch (slot) {
case CastingSlot::Gem1:
return EQEmu::CastingSlot::Gem1;
case CastingSlot::Gem2:
return EQEmu::CastingSlot::Gem2;
case CastingSlot::Gem3:
return EQEmu::CastingSlot::Gem3;
case CastingSlot::Gem4:
return EQEmu::CastingSlot::Gem4;
case CastingSlot::Gem5:
return EQEmu::CastingSlot::Gem5;
case CastingSlot::Gem6:
return EQEmu::CastingSlot::Gem6;
case CastingSlot::Gem7:
return EQEmu::CastingSlot::Gem7;
case CastingSlot::Gem8:
return EQEmu::CastingSlot::Gem8;
case CastingSlot::Gem9:
return EQEmu::CastingSlot::Gem9;
case CastingSlot::Ability:
return EQEmu::CastingSlot::Ability;
// Tit uses 10 for item and discipline casting, but items have a valid location
case CastingSlot::Item:
if (itemlocation == INVALID_INDEX)
return EQEmu::CastingSlot::Discipline;
else
return EQEmu::CastingSlot::Item;
case CastingSlot::PotionBelt:
return EQEmu::CastingSlot::PotionBelt;
case CastingSlot::AltAbility:
return EQEmu::CastingSlot::AltAbility;
default: // we shouldn't have any issues with other slots ... just return something
return EQEmu::CastingSlot::Discipline;
}
}
} /*SoF*/
+17
View File
@@ -50,6 +50,23 @@ namespace SoF
#include "sof_ops.h"
};
enum class CastingSlot : uint32 {
Gem1 = 0,
Gem2 = 1,
Gem3 = 2,
Gem4 = 3,
Gem5 = 4,
Gem6 = 5,
Gem7 = 6,
Gem8 = 7,
Gem9 = 8,
Ability = 9,
Item = 10,
Discipline = 10,
PotionBelt = 11,
AltAbility = 0xFF
};
}; /*SoF*/
#endif /*COMMON_SOF_H*/
+29 -12
View File
@@ -10,7 +10,7 @@
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.
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
@@ -22,7 +22,7 @@
#include "../string_util.h"
size_t SoF::invtype::InvTypeSize(int inv_type)
size_t SoF::invtype::GetInvTypeSize(int inv_type)
{
switch (inv_type) {
case invtype::InvTypePossessions:
@@ -68,7 +68,7 @@ size_t SoF::invtype::InvTypeSize(int inv_type)
}
}
const char* SoF::invtype::InvTypeName(int inv_type)
const char* SoF::invtype::GetInvTypeName(int inv_type)
{
switch (inv_type) {
case invtype::InvTypeInvalid:
@@ -116,7 +116,24 @@ const char* SoF::invtype::InvTypeName(int inv_type)
}
}
const char* SoF::invslot::InvPossessionsSlotName(int inv_slot)
bool SoF::invtype::IsInvTypePersistent(int inv_type)
{
switch (inv_type) {
case invtype::InvTypePossessions:
case invtype::InvTypeBank:
case invtype::InvTypeSharedBank:
case invtype::InvTypeTrade:
case invtype::InvTypeWorld:
case invtype::InvTypeLimbo:
case invtype::InvTypeTribute:
case invtype::InvTypeGuildTribute:
return true;
default:
return false;
}
}
const char* SoF::invslot::GetInvPossessionsSlotName(int inv_slot)
{
switch (inv_slot) {
case invslot::InvSlotInvalid:
@@ -190,9 +207,9 @@ const char* SoF::invslot::InvPossessionsSlotName(int inv_slot)
}
}
const char* SoF::invslot::InvCorpseSlotName(int inv_slot)
const char* SoF::invslot::GetInvCorpseSlotName(int inv_slot)
{
if (!invtype::InvTypeSize(invtype::InvTypeCorpse) || inv_slot == invslot::InvSlotInvalid)
if (!invtype::GetInvTypeSize(invtype::InvTypeCorpse) || inv_slot == invslot::InvSlotInvalid)
return "Invalid Slot";
// needs work
@@ -205,14 +222,14 @@ const char* SoF::invslot::InvCorpseSlotName(int inv_slot)
return ret_str.c_str();
}
const char* SoF::invslot::InvSlotName(int inv_type, int inv_slot)
const char* SoF::invslot::GetInvSlotName(int inv_type, int inv_slot)
{
if (inv_type == invtype::InvTypePossessions)
return invslot::InvPossessionsSlotName(inv_slot);
return invslot::GetInvPossessionsSlotName(inv_slot);
else if (inv_type == invtype::InvTypeCorpse)
return invslot::InvCorpseSlotName(inv_slot);
return invslot::GetInvCorpseSlotName(inv_slot);
size_t type_size = invtype::InvTypeSize(inv_type);
size_t type_size = invtype::GetInvTypeSize(inv_type);
if (!type_size || inv_slot == invslot::InvSlotInvalid)
return "Invalid Slot";
@@ -226,7 +243,7 @@ const char* SoF::invslot::InvSlotName(int inv_type, int inv_slot)
return ret_str.c_str();
}
const char* SoF::invbag::InvBagIndexName(int bag_index)
const char* SoF::invbag::GetInvBagIndexName(int bag_index)
{
if (bag_index == invbag::InvBagInvalid)
return "Invalid Bag";
@@ -240,7 +257,7 @@ const char* SoF::invbag::InvBagIndexName(int bag_index)
return ret_str.c_str();
}
const char* SoF::invaug::InvAugIndexName(int aug_index)
const char* SoF::invaug::GetInvAugIndexName(int aug_index)
{
if (aug_index == invaug::InvAugInvalid)
return "Invalid Augment";
+40 -28
View File
@@ -10,7 +10,7 @@
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.
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
@@ -21,7 +21,7 @@
#define COMMON_SOF_LIMITS_H
#include "../types.h"
#include "../client_version.h"
#include "../emu_versions.h"
#include "../skills.h"
@@ -32,8 +32,13 @@ namespace SoF
enum : bool { False = false, True = true };
// pre-declarations
namespace inventory {
inline EQEmu::versions::ClientVersion GetInventoryRef() { return EQEmu::versions::ClientVersion::SoF; }
} /*inventory*/
namespace invtype {
inline EQEmu::versions::ClientVersion InvTypeRef() { return EQEmu::versions::ClientVersion::SoF; }
inline EQEmu::versions::ClientVersion GetInvTypeRef() { return EQEmu::versions::ClientVersion::SoF; }
enum : int { InvTypeInvalid = -1, InvTypeBegin };
@@ -63,7 +68,7 @@ namespace SoF
} /*invtype*/
namespace invslot {
inline EQEmu::versions::ClientVersion InvSlotRef() { return EQEmu::versions::ClientVersion::SoF; }
inline EQEmu::versions::ClientVersion GetInvSlotRef() { return EQEmu::versions::ClientVersion::SoF; }
enum : int { InvSlotInvalid = -1, InvSlotBegin };
@@ -114,21 +119,21 @@ namespace SoF
} /*invslot*/
namespace invbag {
inline EQEmu::versions::ClientVersion InvBagRef() { return EQEmu::versions::ClientVersion::SoF; }
inline EQEmu::versions::ClientVersion GetInvBagRef() { return EQEmu::versions::ClientVersion::SoF; }
enum : int { InvBagInvalid = -1, InvBagBegin };
} /*invbag*/
namespace invaug {
inline EQEmu::versions::ClientVersion InvAugRef() { return EQEmu::versions::ClientVersion::SoF; }
inline EQEmu::versions::ClientVersion GetInvAugRef() { return EQEmu::versions::ClientVersion::SoF; }
enum : int { InvAugInvalid = -1, InvAugBegin };
} /*invaug*/
namespace item {
inline EQEmu::versions::ClientVersion ItemRef() { return EQEmu::versions::ClientVersion::SoF; }
inline EQEmu::versions::ClientVersion GetItemRef() { return EQEmu::versions::ClientVersion::SoF; }
enum ItemPacketType : int {
ItemPacketMerchant = 100,
@@ -146,27 +151,37 @@ namespace SoF
} /*item*/
namespace profile {
inline EQEmu::versions::ClientVersion ProfileRef() { return EQEmu::versions::ClientVersion::SoF; }
inline EQEmu::versions::ClientVersion GetProfileRef() { return EQEmu::versions::ClientVersion::SoF; }
} /*profile*/
namespace constants {
inline EQEmu::versions::ClientVersion ConstantsRef() { return EQEmu::versions::ClientVersion::SoF; }
inline EQEmu::versions::ClientVersion GetConstantsRef() { return EQEmu::versions::ClientVersion::SoF; }
} /*constants*/
namespace behavior {
inline EQEmu::versions::ClientVersion BehaviorRef() { return EQEmu::versions::ClientVersion::SoF; }
inline EQEmu::versions::ClientVersion GetBehaviorRef() { return EQEmu::versions::ClientVersion::SoF; }
} /*behavior*/
namespace skills {
inline EQEmu::versions::ClientVersion SkillsRef() { return EQEmu::versions::ClientVersion::SoF; }
inline EQEmu::versions::ClientVersion GetSkillsRef() { return EQEmu::versions::ClientVersion::SoF; }
} /*skills*/
// declarations
namespace inventory {
const bool ConcatenateInvTypeLimbo = true;
const bool AllowOverLevelEquipment = false;
const bool AllowEmptyBagInBag = false;
const bool AllowClickCastFromBag = false;
} /*inventory*/
namespace invtype {
const size_t InvTypePossessionsSize = invslot::PossessionsCount;
const size_t InvTypeBankSize = 24;
@@ -175,7 +190,7 @@ namespace SoF
const size_t InvTypeWorldSize = 10;
const size_t InvTypeLimboSize = 36;
const size_t InvTypeTributeSize = 5;
const size_t InvTypeGuildTributeSize = 0;//unknown
const size_t InvTypeGuildTributeSize = 2;
const size_t InvTypeMerchantSize = 80;
const size_t InvTypeCorpseSize = InvTypePossessionsSize;
const size_t InvTypeBazaarSize = 80;
@@ -188,10 +203,10 @@ namespace SoF
const size_t InvTypeArchivedSize = 0;//unknown
const size_t InvTypeOtherSize = 0;//unknown
const size_t NPCTradeSize = 4;
extern size_t GetInvTypeSize(int inv_type);
extern const char* GetInvTypeName(int inv_type);
extern size_t InvTypeSize(int inv_type);
extern const char* InvTypeName(int inv_type);
extern bool IsInvTypePersistent(int inv_type);
} /*invtype*/
@@ -210,14 +225,17 @@ namespace SoF
const int WorldEnd = (WorldBegin + invtype::InvTypeWorldSize) - 1;
const int TributeBegin = 400;
const int TributeEnd = 404;
const int TributeEnd = (TributeBegin + invtype::InvTypeTributeSize) - 1;
const int GuildTributeBegin = 450;
const int GuildTributeEnd = (GuildTributeBegin + invtype::InvTypeGuildTributeSize) - 1;
const int CorpseBegin = PossessionsGeneral1;
const int CorpseEnd = PossessionsGeneral1 + PossessionsCursor;
extern const char* InvPossessionsSlotName(int inv_slot);
extern const char* InvCorpseSlotName(int inv_slot);
extern const char* InvSlotName(int inv_type, int inv_slot);
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*/
@@ -244,14 +262,14 @@ namespace SoF
const int TradeBagsSize = invtype::InvTypeTradeSize * ItemBagSize;
const int TradeBagsEnd = (TradeBagsBegin + TradeBagsSize) - 1;
extern const char* InvBagIndexName(int bag_index);
extern const char* GetInvBagIndexName(int bag_index);
} /*invbag*/
namespace invaug {
const size_t ItemAugSize = 5;
extern const char* InvAugIndexName(int aug_index);
extern const char* GetInvAugIndexName(int aug_index);
} /*invaug*/
@@ -261,6 +279,7 @@ namespace SoF
namespace profile {
const size_t TributeSize = invtype::InvTypeTributeSize;
const size_t GuildTributeSize = invtype::InvTypeGuildTributeSize;
const size_t BandoliersSize = 20; // number of bandolier instances
const size_t BandolierItemCount = 4; // number of equipment slots in bandolier instance
@@ -279,13 +298,6 @@ namespace SoF
} /*constants*/
namespace behavior {
const bool ConcatenateInvTypeLimbo = true;
const bool AllowOverLevelEquipment = false;
const bool AllowEmptyBagInBag = false;
const bool AllowClickCastFromBag = false;
const bool CoinHasWeight = true;
} /*behavior*/
+2
View File
@@ -57,6 +57,7 @@ E(OP_LeadershipExpUpdate)
E(OP_LogServer)
E(OP_LootItem)
E(OP_ManaChange)
E(OP_MemorizeSpell)
E(OP_MoveItem)
E(OP_NewSpawn)
E(OP_NewZone)
@@ -110,6 +111,7 @@ D(OP_GroupFollow2)
D(OP_InspectRequest)
D(OP_ItemLinkClick)
D(OP_ItemVerifyRequest)
D(OP_LoadSpellSet)
D(OP_LootItem)
D(OP_MoveItem)
D(OP_PetCommands)
+78 -118
View File
@@ -122,7 +122,7 @@ struct AdventureInfo {
** Merth: Gave struct a name so gcc 2.96 would compile
**
*/
struct Color_Struct
struct Tint_Struct
{
union {
struct {
@@ -130,19 +130,62 @@ struct Color_Struct
uint8 Green;
uint8 Red;
uint8 UseTint; // if there's a tint this is FF
} RGB;
};
uint32 Color;
};
};
struct CharSelectEquip
struct TintProfile
{
union {
struct {
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;
};
Tint_Struct Slot[EQEmu::textures::TextureCount];
};
};
/*
* Visible equiptment.
* Size: 12 Octets
*/
struct Texture_Struct
{
uint32 Material;
uint32 Unknown1;
uint32 EliteMaterial;
Color_Struct Color;
};
struct TextureProfile
{
union {
struct {
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;
};
Texture_Struct Slot[EQEmu::textures::TextureCount];
};
TextureProfile();
};
struct CharSelectEquip : Texture_Struct, Tint_Struct {};
struct CharacterSelectEntry_Struct
{
/*0000*/ uint8 Level; //
@@ -152,7 +195,7 @@ struct CharacterSelectEntry_Struct
/*0000*/ uint8 Beard; //
/*0001*/ uint8 HairColor; //
/*0000*/ uint8 Face; //
/*0000*/ CharSelectEquip Equip[9];
/*0000*/ CharSelectEquip Equip[EQEmu::textures::TextureCount];
/*0000*/ uint32 PrimaryIDFile; //
/*0000*/ uint32 SecondaryIDFile; //
/*0000*/ uint8 Unknown15; // 0xff
@@ -183,19 +226,6 @@ struct CharacterSelect_Struct
/*0008*/ CharacterSelectEntry_Struct Entries[0];
};
/*
* Visible equiptment.
* Size: 12 Octets
*/
struct EquipStruct
{
/*00*/ uint32 Material;
/*04*/ uint32 Unknown1;
/*08*/ uint32 EliteMaterial;
/*12*/
};
/*
** Generic Spawn Struct
** Length: 897 Octets
@@ -222,22 +252,7 @@ struct Spawn_Struct {
/*0018*/ uint8 unknown0018[4]; //
/*0022*/ uint8 gender; // Gender (0=male, 1=female, 2=monster)
/*0023*/ uint8 unknown0023[4]; //
/*0027*/ union
{
struct
{
/*0027*/ EquipStruct equip_helmet; // Equiptment: Helmet visual
/*0039*/ EquipStruct equip_chest; // Equiptment: Chest visual
/*0051*/ EquipStruct equip_arms; // Equiptment: Arms visual
/*0063*/ EquipStruct equip_bracers; // Equiptment: Wrist visual
/*0075*/ EquipStruct equip_hands; // Equiptment: Hands visual
/*0087*/ EquipStruct equip_legs; // Equiptment: Legs visual
/*0099*/ EquipStruct equip_feet; // Equiptment: Boots visual
/*0111*/ EquipStruct equip_primary; // Equiptment: Main visual
/*0123*/ EquipStruct equip_secondary; // Equiptment: Off visual
} equip;
/*0027*/ EquipStruct equipment[9];
};
/*0027*/ TextureProfile equipment;
/*0135*/ uint8 StandState; // Seems to be required to be set to 0x64 for normal animation.
/*0136*/ uint8 unknown0136;
@@ -314,22 +329,7 @@ union
/*0775*/ char name[64]; // Player's Name
/*0839*/ uint32 petOwnerId; // If this is a pet, the spawn id of owner
/*0843*/ uint8 pvp; // 0 = normal name color, 2 = PVP name color
/*0844*/ union
{
struct
{
/*0844*/ Color_Struct color_helmet; // Color of helmet item
/*0848*/ Color_Struct color_chest; // Color of chest item
/*0852*/ Color_Struct color_arms; // Color of arms item
/*0856*/ Color_Struct color_bracers; // Color of bracers item
/*0860*/ Color_Struct color_hands; // Color of hands item
/*0864*/ Color_Struct color_legs; // Color of legs item
/*0868*/ Color_Struct color_feet; // Color of feet item
/*0872*/ Color_Struct color_primary; // Color of primary item
/*0876*/ Color_Struct color_secondary; // Color of secondary item
} equipment_colors;
/*0844*/ Color_Struct colors[9]; // Array elements correspond to struct equipment_colors above
};
/*0844*/ TintProfile equipment_tint;
/*0880*/ uint8 anon; // 0=normal, 1=anon, 2=roleplay
/*0881*/ uint8 face;
/*0882*/ uint8 drakkin_details; // Face Details (Spikes) on Drakkin 0 - 7
@@ -458,7 +458,7 @@ struct MemorizeSpell_Struct {
uint32 slot; // Spot in the spell book/memorized slot
uint32 spell_id; // Spell id (200 or c8 is minor healing, etc)
uint32 scribing; // 1 if memorizing a spell, set to 0 if scribing to book, 2 if un-memming
//uint32 unknown12;
uint32 reduction; // lowers reuse
};
/*
@@ -491,11 +491,12 @@ struct DeleteSpell_Struct
struct ManaChange_Struct
{
uint32 new_mana; // New Mana AMount
uint32 stamina;
uint32 spell_id;
uint32 unknown12;
uint32 unknown16;
/*00*/ uint32 new_mana; // New Mana AMount
/*04*/ uint32 stamina;
/*08*/ uint32 spell_id;
/*12*/ uint8 keepcasting; // won't stop the cast. Change mana while casting?
/*13*/ uint8 padding[3]; // client doesn't read it, garbage data seems like
/*16*/ int32 slot; // -1 for normal usage slot for when we want silent interrupt? I think it does timer stuff or something. Linked Spell Reuse interrupt uses it
};
struct SwapSpell_Struct
@@ -542,32 +543,23 @@ struct SpawnAppearance_Struct
// this is used inside profile
struct SpellBuff_Struct
{
/*000*/ uint8 slotid; //badly named... seems to be 2 for a real buff, 0 otherwise
/*001*/ uint8 level;
/*002*/ uint8 bard_modifier;
/*003*/ uint8 effect; //not real
/*004*/ uint32 spellid;
/*008*/ int32 duration;
/*012*/ uint32 counters;
/*016*/ uint32 unknown004; //Might need to be swapped with player_id
/*020*/ uint32 player_id; //'global' ID of the caster, for wearoff messages
/*000*/ uint8 effect_type; // 0 = no buff, 2 = buff, 4 = inverse affects of buff
/*001*/ uint8 level; // Seen 1 for no buff
/*002*/ uint8 bard_modifier;
/*003*/ uint8 unknown003; // MQ2 used to call this "damage shield" -- don't see client referencing it, so maybe server side DS type tracking?
/*004*/ uint32 spellid;
/*008*/ uint32 duration;
/*012*/ uint32 counters;
/*016*/ uint32 unknown016;
/*020*/ uint32 player_id; // caster ID, pretty sure just zone ID
/*024*/
};
struct SpellBuffFade_Struct {
struct SpellBuffPacket_Struct {
/*000*/ uint32 entityid;
/*004*/ uint8 slot;
/*005*/ uint8 level;
/*006*/ uint8 effect;
/*007*/ uint8 unknown7;
/*008*/ uint32 spellid;
/*012*/ int32 duration;
/*016*/ uint32 unknown016;
/*020*/ uint32 unknown020; //prolly global player ID
/*024*/ uint32 playerId; // Player id who cast the buff
/*004*/ SpellBuff_Struct buff;
/*028*/ uint32 slotid;
/*032*/ uint32 bufffade;
/*036*/
@@ -882,24 +874,9 @@ struct PlayerProfile_Struct //23576 Octets
/*00216*/ uint8 hairstyle; // Player hair style
/*00217*/ uint8 beard; // Player beard type
/*00218*/ uint8 unknown00178[10]; //[10]14 on Live?
/*00228*/ union
{
struct
{
/*00228*/ EquipStruct equip_helmet; // Equiptment: Helmet visual
/*00240*/ EquipStruct equip_chest; // Equiptment: Chest visual
/*00252*/ EquipStruct equip_arms; // Equiptment: Arms visual
/*00264*/ EquipStruct equip_bracers; // Equiptment: Wrist visual
/*00276*/ EquipStruct equip_hands; // Equiptment: Hands visual
/*00288*/ EquipStruct equip_legs; // Equiptment: Legs visual
/*00300*/ EquipStruct equip_feet; // Equiptment: Boots visual
/*00312*/ EquipStruct equip_primary; // Equiptment: Main visual
/*00324*/ EquipStruct equip_secondary; // Equiptment: Off visual
} equip;
/*00228*/ EquipStruct equipment[9]; //Live Shows [108] for this part
};
/*00228*/ TextureProfile equipment;
/*00336*/ uint8 unknown00224[156]; // Live Shows [160]
/*00496*/ Color_Struct item_tint[9]; // RR GG BB 00
/*00496*/ TintProfile item_tint; // RR GG BB 00
/*00544*/ AA_Array aa_array[MAX_PP_AA_ARRAY]; // [3600] AAs 12 bytes each
/*04132*/ uint32 points; // Unspent Practice points - RELOCATED???
/*04136*/ uint32 mana; // Current mana
@@ -1155,7 +1132,7 @@ struct WearChange_Struct{
/*002*/ uint32 material;
/*006*/ uint32 unknown06;
/*010*/ uint32 elite_material; // 1 for Drakkin Elite Material
/*014*/ Color_Struct color;
/*014*/ Tint_Struct color;
/*018*/ uint8 wear_slot_id;
/*019*/
};
@@ -1882,8 +1859,7 @@ struct Merchant_Sell_Struct {
/*004*/ uint32 playerid; // Player's entity id
/*008*/ uint32 itemslot;
uint32 unknown12;
/*016*/ uint8 quantity; // Already sold
/*017*/ uint8 Unknown016[3];
/*016*/ uint32 quantity;
/*020*/ uint32 price;
};
struct Merchant_Purchase_Struct {
@@ -2954,27 +2930,6 @@ struct PetitionBug_Struct{
char text[1028];
};
struct DyeStruct
{
union
{
struct
{
struct Color_Struct head;
struct Color_Struct chest;
struct Color_Struct arms;
struct Color_Struct wrists;
struct Color_Struct hands;
struct Color_Struct legs;
struct Color_Struct feet;
struct Color_Struct primary; // you can't actually dye this
struct Color_Struct secondary; // or this
}
dyes;
struct Color_Struct dye[9];
};
};
struct ApproveZone_Struct {
char name[64];
uint32 zoneid;
@@ -3773,6 +3728,11 @@ 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;
+203 -20
View File
@@ -58,6 +58,9 @@ namespace Titanium
// client to server text link converter
static inline void TitaniumToServerTextLink(std::string& serverTextLink, const std::string& titaniumTextLink);
static inline CastingSlot ServerToTitaniumCastingSlot(EQEmu::CastingSlot slot);
static inline EQEmu::CastingSlot TitaniumToServerCastingSlot(CastingSlot slot, uint32 itemlocation);
void Register(EQStreamIdentifier &into)
{
auto Config = EQEmuConfig::get();
@@ -254,6 +257,25 @@ namespace Titanium
FINISH_ENCODE();
}
ENCODE(OP_Buff)
{
ENCODE_LENGTH_EXACT(SpellBuffPacket_Struct);
SETUP_DIRECT_ENCODE(SpellBuffPacket_Struct, structs::SpellBuffPacket_Struct);
OUT(entityid);
OUT(buff.effect_type);
OUT(buff.level);
OUT(buff.bard_modifier);
OUT(buff.spellid);
OUT(buff.duration);
OUT(buff.counters);
OUT(buff.player_id);
OUT(slotid);
OUT(bufffade);
FINISH_ENCODE();
}
ENCODE(OP_ChannelMessage)
{
EQApplicationPacket *in = *p;
@@ -573,6 +595,46 @@ 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
@@ -814,6 +876,22 @@ namespace Titanium
FINISH_ENCODE();
}
ENCODE(OP_MemorizeSpell)
{
ENCODE_LENGTH_EXACT(MemorizeSpell_Struct);
SETUP_DIRECT_ENCODE(MemorizeSpell_Struct, structs::MemorizeSpell_Struct);
// Since HT/LoH are translated up, we need to translate down only for memSpellSpellbar case
if (emu->scribing == 3)
eq->slot = static_cast<uint32>(ServerToTitaniumCastingSlot(static_cast<EQEmu::CastingSlot>(emu->slot)));
else
OUT(slot);
OUT(spell_id);
OUT(scribing);
FINISH_ENCODE();
}
ENCODE(OP_MoveItem)
{
ENCODE_LENGTH_EXACT(MoveItem_Struct);
@@ -853,9 +931,9 @@ namespace Titanium
OUT(petid);
OUT(buffcount);
int EQBuffSlot = 0;
int EQBuffSlot = 0; // do we really want to shuffle them around like this?
for (uint32 EmuBuffSlot = 0; EmuBuffSlot < BUFF_COUNT; ++EmuBuffSlot)
for (uint32 EmuBuffSlot = 0; EmuBuffSlot < PET_BUFF_COUNT; ++EmuBuffSlot)
{
if (emu->spellid[EmuBuffSlot])
{
@@ -903,9 +981,9 @@ namespace Titanium
OUT(hairstyle);
OUT(beard);
// OUT(unknown00178[10]);
for (r = 0; r < 9; r++) {
OUT(item_material[r]);
OUT(item_tint[r].Color);
for (r = EQEmu::textures::TextureBegin; r < EQEmu::textures::TextureCount; r++) {
OUT(item_material.Slot[r].Material);
OUT(item_tint.Slot[r].Color);
}
// OUT(unknown00224[48]);
for (r = 0; r < structs::MAX_PP_AA_ARRAY; r++) {
@@ -945,10 +1023,10 @@ namespace Titanium
OUT(thirst_level);
OUT(hunger_level);
for (r = 0; r < structs::BUFF_COUNT; r++) {
OUT(buffs[r].slotid);
OUT(buffs[r].effect_type);
OUT(buffs[r].level);
OUT(buffs[r].bard_modifier);
OUT(buffs[r].effect);
OUT(buffs[r].unknown003);
OUT(buffs[r].spellid);
OUT(buffs[r].duration);
OUT(buffs[r].counters);
@@ -1223,15 +1301,15 @@ namespace Titanium
if (eq->Race[char_index] > 473)
eq->Race[char_index] = 1;
for (int index = 0; index < EQEmu::legacy::MaterialCount; ++index) {
eq->CS_Colors[char_index][index].Color = emu_cse->Equip[index].Color.Color;
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::legacy::MaterialCount; ++index) {
eq->Equip[char_index][index] = emu_cse->Equip[index].Material;
for (int index = 0; index < EQEmu::textures::TextureCount; ++index) {
eq->Equip[char_index].Slot[index].Material = emu_cse->Equip[index].Material;
}
eq->SecondaryIDFile[char_index] = emu_cse->SecondaryIDFile;
@@ -1260,15 +1338,15 @@ namespace Titanium
for (; char_index < 10; ++char_index) {
eq->Race[char_index] = 0;
for (int index = 0; index < EQEmu::legacy::MaterialCount; ++index) {
eq->CS_Colors[char_index][index].Color = 0;
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::legacy::MaterialCount; ++index) {
eq->Equip[char_index][index] = 0;
for (int index = 0; index < EQEmu::textures::TextureCount; ++index) {
eq->Equip[char_index].Slot[index].Material = 0;
}
eq->SecondaryIDFile[char_index] = 0;
@@ -1599,9 +1677,9 @@ namespace Titanium
eq->petOwnerId = emu->petOwnerId;
eq->guildrank = emu->guildrank;
// eq->unknown0194[3] = emu->unknown0194[3];
for (k = 0; k < 9; k++) {
eq->equipment[k] = emu->equipment[k].Material;
eq->colors[k].Color = emu->colors[k].Color;
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;
}
for (k = 0; k < 8; k++) {
eq->set_to_0xFF[k] = 0xFF;
@@ -1688,12 +1766,31 @@ namespace Titanium
FINISH_DIRECT_DECODE();
}
DECODE(OP_Buff)
{
DECODE_LENGTH_EXACT(structs::SpellBuffPacket_Struct);
SETUP_DIRECT_DECODE(SpellBuffPacket_Struct, structs::SpellBuffPacket_Struct);
IN(entityid);
IN(buff.effect_type);
IN(buff.level);
IN(buff.bard_modifier);
IN(buff.spellid);
IN(buff.duration);
IN(buff.counters);
IN(buff.player_id);
IN(slotid);
IN(bufffade);
FINISH_DIRECT_DECODE();
}
DECODE(OP_CastSpell)
{
DECODE_LENGTH_EXACT(structs::CastSpell_Struct);
SETUP_DIRECT_DECODE(CastSpell_Struct, structs::CastSpell_Struct);
IN(slot);
emu->slot = static_cast<uint32>(TitaniumToServerCastingSlot(static_cast<CastingSlot>(eq->slot), eq->inventoryslot));
IN(spell_id);
emu->inventoryslot = TitaniumToServerSlot(eq->inventoryslot);
IN(target_id);
@@ -1881,6 +1978,21 @@ 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);
@@ -2107,7 +2219,7 @@ namespace Titanium
void SerializeItem(EQEmu::OutBuffer& ob, const ItemInst *inst, int16 slot_id_in, uint8 depth)
{
const char* protection = "\\\\\\\\\\";
const EQEmu::Item_Struct* 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;
@@ -2449,4 +2561,75 @@ namespace Titanium
}
}
static inline CastingSlot ServerToTitaniumCastingSlot(EQEmu::CastingSlot slot)
{
switch (slot) {
case EQEmu::CastingSlot::Gem1:
return CastingSlot::Gem1;
case EQEmu::CastingSlot::Gem2:
return CastingSlot::Gem2;
case EQEmu::CastingSlot::Gem3:
return CastingSlot::Gem3;
case EQEmu::CastingSlot::Gem4:
return CastingSlot::Gem4;
case EQEmu::CastingSlot::Gem5:
return CastingSlot::Gem5;
case EQEmu::CastingSlot::Gem6:
return CastingSlot::Gem6;
case EQEmu::CastingSlot::Gem7:
return CastingSlot::Gem7;
case EQEmu::CastingSlot::Gem8:
return CastingSlot::Gem8;
case EQEmu::CastingSlot::Gem9:
return CastingSlot::Gem9;
case EQEmu::CastingSlot::Item:
return CastingSlot::Item;
case EQEmu::CastingSlot::PotionBelt:
return CastingSlot::PotionBelt;
case EQEmu::CastingSlot::Discipline:
return CastingSlot::Discipline;
case EQEmu::CastingSlot::AltAbility:
return CastingSlot::AltAbility;
default: // we shouldn't have any issues with other slots ... just return something
return CastingSlot::Discipline;
}
}
static inline EQEmu::CastingSlot TitaniumToServerCastingSlot(CastingSlot slot, uint32 itemlocation)
{
switch (slot) {
case CastingSlot::Gem1:
return EQEmu::CastingSlot::Gem1;
case CastingSlot::Gem2:
return EQEmu::CastingSlot::Gem2;
case CastingSlot::Gem3:
return EQEmu::CastingSlot::Gem3;
case CastingSlot::Gem4:
return EQEmu::CastingSlot::Gem4;
case CastingSlot::Gem5:
return EQEmu::CastingSlot::Gem5;
case CastingSlot::Gem6:
return EQEmu::CastingSlot::Gem6;
case CastingSlot::Gem7:
return EQEmu::CastingSlot::Gem7;
case CastingSlot::Gem8:
return EQEmu::CastingSlot::Gem8;
case CastingSlot::Gem9:
return EQEmu::CastingSlot::Gem9;
case CastingSlot::Ability:
return EQEmu::CastingSlot::Ability;
// Tit uses 10 for item and discipline casting, but items have a valid location
case CastingSlot::Item:
if (itemlocation == INVALID_INDEX)
return EQEmu::CastingSlot::Discipline;
else
return EQEmu::CastingSlot::Item;
case CastingSlot::PotionBelt:
return EQEmu::CastingSlot::PotionBelt;
case CastingSlot::AltAbility:
return EQEmu::CastingSlot::AltAbility;
default: // we shouldn't have any issues with other slots ... just return something
return EQEmu::CastingSlot::Discipline;
}
}
} /*Titanium*/
+17
View File
@@ -50,6 +50,23 @@ namespace Titanium
#include "titanium_ops.h"
};
enum class CastingSlot : uint32 {
Gem1 = 0,
Gem2 = 1,
Gem3 = 2,
Gem4 = 3,
Gem5 = 4,
Gem6 = 5,
Gem7 = 6,
Gem8 = 7,
Gem9 = 8,
Ability = 9,
Item = 10,
Discipline = 10,
PotionBelt = 11,
AltAbility = 0xFF
};
}; /*Titanium*/
#endif /*COMMON_TITANIUM_H*/
+29 -12
View File
@@ -10,7 +10,7 @@
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.
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
@@ -22,7 +22,7 @@
#include "../string_util.h"
size_t Titanium::invtype::InvTypeSize(int inv_type)
size_t Titanium::invtype::GetInvTypeSize(int inv_type)
{
switch (inv_type) {
case invtype::InvTypePossessions:
@@ -68,7 +68,7 @@ size_t Titanium::invtype::InvTypeSize(int inv_type)
}
}
const char* Titanium::invtype::InvTypeName(int inv_type)
const char* Titanium::invtype::GetInvTypeName(int inv_type)
{
switch (inv_type) {
case invtype::InvTypeInvalid:
@@ -116,7 +116,24 @@ const char* Titanium::invtype::InvTypeName(int inv_type)
}
}
const char* Titanium::invslot::InvPossessionsSlotName(int inv_slot)
bool Titanium::invtype::IsInvTypePersistent(int inv_type)
{
switch (inv_type) {
case invtype::InvTypePossessions:
case invtype::InvTypeBank:
case invtype::InvTypeSharedBank:
case invtype::InvTypeTrade:
case invtype::InvTypeWorld:
case invtype::InvTypeLimbo:
case invtype::InvTypeTribute:
case invtype::InvTypeGuildTribute:
return true;
default:
return false;
}
}
const char* Titanium::invslot::GetInvPossessionsSlotName(int inv_slot)
{
switch (inv_slot) {
case invslot::InvSlotInvalid:
@@ -188,9 +205,9 @@ const char* Titanium::invslot::InvPossessionsSlotName(int inv_slot)
}
}
const char* Titanium::invslot::InvCorpseSlotName(int inv_slot)
const char* Titanium::invslot::GetInvCorpseSlotName(int inv_slot)
{
if (!invtype::InvTypeSize(invtype::InvTypeCorpse) || inv_slot == invslot::InvSlotInvalid)
if (!invtype::GetInvTypeSize(invtype::InvTypeCorpse) || inv_slot == invslot::InvSlotInvalid)
return "Invalid Slot";
// needs work
@@ -203,14 +220,14 @@ const char* Titanium::invslot::InvCorpseSlotName(int inv_slot)
return ret_str.c_str();
}
const char* Titanium::invslot::InvSlotName(int inv_type, int inv_slot)
const char* Titanium::invslot::GetInvSlotName(int inv_type, int inv_slot)
{
if (inv_type == invtype::InvTypePossessions)
return invslot::InvPossessionsSlotName(inv_slot);
return invslot::GetInvPossessionsSlotName(inv_slot);
else if (inv_type == invtype::InvTypeCorpse)
return invslot::InvCorpseSlotName(inv_slot);
return invslot::GetInvCorpseSlotName(inv_slot);
size_t type_size = invtype::InvTypeSize(inv_type);
size_t type_size = invtype::GetInvTypeSize(inv_type);
if (!type_size || inv_slot == invslot::InvSlotInvalid)
return "Invalid Slot";
@@ -224,7 +241,7 @@ const char* Titanium::invslot::InvSlotName(int inv_type, int inv_slot)
return ret_str.c_str();
}
const char* Titanium::invbag::InvBagIndexName(int bag_index)
const char* Titanium::invbag::GetInvBagIndexName(int bag_index)
{
if (bag_index == invbag::InvBagInvalid)
return "Invalid Bag";
@@ -238,7 +255,7 @@ const char* Titanium::invbag::InvBagIndexName(int bag_index)
return ret_str.c_str();
}
const char* Titanium::invaug::InvAugIndexName(int aug_index)
const char* Titanium::invaug::GetInvAugIndexName(int aug_index)
{
if (aug_index == invaug::InvAugInvalid)
return "Invalid Augment";
+40 -28
View File
@@ -10,7 +10,7 @@
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.
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
@@ -21,7 +21,7 @@
#define COMMON_TITANIUM_LIMITS_H
#include "../types.h"
#include "../client_version.h"
#include "../emu_versions.h"
#include "../skills.h"
@@ -32,8 +32,13 @@ namespace Titanium
enum : bool { False = false, True = true };
// pre-declarations
namespace inventory {
inline EQEmu::versions::ClientVersion GetInventoryRef() { return EQEmu::versions::ClientVersion::Titanium; }
} /*inventory*/
namespace invtype {
inline EQEmu::versions::ClientVersion InvTypeRef() { return EQEmu::versions::ClientVersion::Titanium; }
inline EQEmu::versions::ClientVersion GetInvTypeRef() { return EQEmu::versions::ClientVersion::Titanium; }
enum : int { InvTypeInvalid = -1, InvTypeBegin };
@@ -63,7 +68,7 @@ namespace Titanium
} /*invtype*/
namespace invslot {
inline EQEmu::versions::ClientVersion InvSlotRef() { return EQEmu::versions::ClientVersion::Titanium; }
inline EQEmu::versions::ClientVersion GetInvSlotRef() { return EQEmu::versions::ClientVersion::Titanium; }
enum : int { InvSlotInvalid = -1, InvSlotBegin };
@@ -113,21 +118,21 @@ namespace Titanium
} /*invslot*/
namespace invbag {
inline EQEmu::versions::ClientVersion InvBagRef() { return EQEmu::versions::ClientVersion::Titanium; }
inline EQEmu::versions::ClientVersion GetInvBagRef() { return EQEmu::versions::ClientVersion::Titanium; }
enum : int { InvBagInvalid = -1, InvBagBegin };
} /*invbag*/
namespace invaug {
inline EQEmu::versions::ClientVersion InvAugRef() { return EQEmu::versions::ClientVersion::Titanium; }
inline EQEmu::versions::ClientVersion GetInvAugRef() { return EQEmu::versions::ClientVersion::Titanium; }
enum : int { InvAugInvalid = -1, InvAugBegin };
} /*invaug*/
namespace item {
inline EQEmu::versions::ClientVersion ItemRef() { return EQEmu::versions::ClientVersion::Titanium; }
inline EQEmu::versions::ClientVersion GetItemRef() { return EQEmu::versions::ClientVersion::Titanium; }
enum ItemPacketType : int {
ItemPacketMerchant = 100,
@@ -145,27 +150,37 @@ namespace Titanium
} /*item*/
namespace profile {
inline EQEmu::versions::ClientVersion ProfileRef() { return EQEmu::versions::ClientVersion::Titanium; }
inline EQEmu::versions::ClientVersion GetProfileRef() { return EQEmu::versions::ClientVersion::Titanium; }
} /*profile*/
namespace constants {
inline EQEmu::versions::ClientVersion ConstantsRef() { return EQEmu::versions::ClientVersion::Titanium; }
inline EQEmu::versions::ClientVersion GetConstantsRef() { return EQEmu::versions::ClientVersion::Titanium; }
} /*constants*/
namespace behavior {
inline EQEmu::versions::ClientVersion BehaviorRef() { return EQEmu::versions::ClientVersion::Titanium; }
inline EQEmu::versions::ClientVersion GetBehaviorRef() { return EQEmu::versions::ClientVersion::Titanium; }
} /*behavior*/
namespace skills {
inline EQEmu::versions::ClientVersion SkillsRef() { return EQEmu::versions::ClientVersion::Titanium; }
inline EQEmu::versions::ClientVersion GetSkillsRef() { return EQEmu::versions::ClientVersion::Titanium; }
} /*skills*/
// declarations
namespace inventory {
const bool ConcatenateInvTypeLimbo = true;
const bool AllowOverLevelEquipment = false;
const bool AllowEmptyBagInBag = false;
const bool AllowClickCastFromBag = false;
} /*inventory*/
namespace invtype {
const size_t InvTypePossessionsSize = invslot::PossessionsCount;
const size_t InvTypeBankSize = 16;
@@ -174,7 +189,7 @@ namespace Titanium
const size_t InvTypeWorldSize = 10;
const size_t InvTypeLimboSize = 36;
const size_t InvTypeTributeSize = 5;
const size_t InvTypeGuildTributeSize = 0;//unknown
const size_t InvTypeGuildTributeSize = 2;
const size_t InvTypeMerchantSize = 80;
const size_t InvTypeCorpseSize = InvTypePossessionsSize;
const size_t InvTypeBazaarSize = 80;
@@ -187,10 +202,10 @@ namespace Titanium
const size_t InvTypeArchivedSize = 0;//unknown
const size_t InvTypeOtherSize = 0;//unknown
const size_t NPCTradeSize = 4;
extern size_t GetInvTypeSize(int inv_type);
extern const char* GetInvTypeName(int inv_type);
extern size_t InvTypeSize(int inv_type);
extern const char* InvTypeName(int inv_type);
extern bool IsInvTypePersistent(int inv_type);
} /*invtype*/
@@ -209,14 +224,17 @@ namespace Titanium
const int WorldEnd = (WorldBegin + invtype::InvTypeWorldSize) - 1;
const int TributeBegin = 400;
const int TributeEnd = 404;
const int TributeEnd = (TributeBegin + invtype::InvTypeTributeSize) - 1;
const int GuildTributeBegin = 450;
const int GuildTributeEnd = (GuildTributeBegin + invtype::InvTypeGuildTributeSize) - 1;
const int CorpseBegin = PossessionsGeneral1;
const int CorpseEnd = PossessionsGeneral1 + PossessionsCursor;
extern const char* InvPossessionsSlotName(int inv_slot);
extern const char* InvCorpseSlotName(int inv_slot);
extern const char* InvSlotName(int inv_type, int inv_slot);
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*/
@@ -243,14 +261,14 @@ namespace Titanium
const int TradeBagsSize = invtype::InvTypeTradeSize * ItemBagSize;
const int TradeBagsEnd = (TradeBagsBegin + TradeBagsSize) - 1;
extern const char* InvBagIndexName(int bag_index);
extern const char* GetInvBagIndexName(int bag_index);
} /*invbag*/
namespace invaug {
const size_t ItemAugSize = 5;
extern const char* InvAugIndexName(int aug_index);
extern const char* GetInvAugIndexName(int aug_index);
} /*invaug*/
@@ -260,6 +278,7 @@ namespace Titanium
namespace profile {
const size_t TributeSize = invtype::InvTypeTributeSize;
const size_t GuildTributeSize = invtype::InvTypeGuildTributeSize;
const size_t BandoliersSize = 4; // number of bandolier instances
const size_t BandolierItemCount = 4; // number of equipment slots in bandolier instance
@@ -278,13 +297,6 @@ namespace Titanium
} /*constants*/
namespace behavior {
const bool ConcatenateInvTypeLimbo = true;
const bool AllowOverLevelEquipment = false;
const bool AllowEmptyBagInBag = false;
const bool AllowClickCastFromBag = false;
const bool CoinHasWeight = true;
} /*behavior*/
+5
View File
@@ -24,6 +24,7 @@ E(OP_AdventureMerchantSell)
E(OP_ApplyPoison)
E(OP_BazaarSearch)
E(OP_BecomeTrader)
E(OP_Buff)
E(OP_ChannelMessage)
E(OP_CharInventory)
E(OP_Damage)
@@ -39,6 +40,7 @@ E(OP_DzLeaderStatus)
E(OP_DzMemberList)
E(OP_Emote)
E(OP_FormattedMessage)
E(OP_GroundSpawn)
E(OP_GuildMemberLevelUpdate)
E(OP_GuildMemberList)
E(OP_Illusion)
@@ -49,6 +51,7 @@ E(OP_ItemPacket)
E(OP_LeadershipExpUpdate)
E(OP_LFGuild)
E(OP_LootItem)
E(OP_MemorizeSpell)
E(OP_MoveItem)
E(OP_OnLevelMessage)
E(OP_PetBuffWindow)
@@ -74,6 +77,7 @@ E(OP_ZoneSpawns)
D(OP_AdventureMerchantSell)
D(OP_ApplyPoison)
D(OP_AugmentItem)
D(OP_Buff)
D(OP_CastSpell)
D(OP_ChannelMessage)
D(OP_CharacterCreate)
@@ -85,6 +89,7 @@ D(OP_InspectAnswer)
D(OP_InspectRequest)
D(OP_ItemLinkClick)
D(OP_LFGuild)
D(OP_LoadSpellSet)
D(OP_LootItem)
D(OP_MoveItem)
D(OP_PetCommands)
+69 -81
View File
@@ -118,7 +118,7 @@ struct AdventureInfo {
** Merth: Gave struct a name so gcc 2.96 would compile
**
*/
struct Color_Struct
struct Tint_Struct
{
union {
struct {
@@ -126,11 +126,53 @@ struct Color_Struct
uint8 Green;
uint8 Red;
uint8 UseTint; // if there's a tint this is FF
} RGB;
};
uint32 Color;
};
};
struct TintProfile {
union {
struct {
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;
};
Tint_Struct Slot[EQEmu::textures::TextureCount];
};
};
struct Texture_Struct
{
uint32 Material;
};
struct TextureProfile
{
union {
struct {
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;
};
Texture_Struct Slot[EQEmu::textures::TextureCount];
};
TextureProfile();
};
/*
** Character Selection Struct
** Length: 1704 Bytes
@@ -139,10 +181,10 @@ struct Color_Struct
struct CharacterSelect_Struct
{
/*0000*/ uint32 Race[10]; // Characters Race
/*0040*/ Color_Struct CS_Colors[10][9]; // Characters Equipment Colors
/*0040*/ TintProfile CS_Colors[10]; // Characters Equipment Colors - packet requires length for 10 characters..but, client is limited to 8
/*0400*/ uint8 BeardColor[10]; // Characters beard Color
/*0410*/ uint8 HairStyle[10]; // Characters hair style
/*0420*/ uint32 Equip[10][9]; // 0=helm, 1=chest, 2=arm, 3=bracer, 4=hand, 5=leg, 6=boot, 7=melee1, 8=melee2 (Might not be)
/*0420*/ TextureProfile Equip[10]; // Characters texture array
/*0780*/ uint32 SecondaryIDFile[10]; // Characters secondary IDFile number
/*0820*/ uint8 Unknown820[10]; // 10x ff
/*0830*/ uint8 Unknown830[2]; // 2x 00
@@ -239,22 +281,7 @@ struct Spawn_Struct {
/*0189*/ uint32 petOwnerId; // If this is a pet, the spawn id of owner
/*0193*/ uint8 guildrank; // 0=normal, 1=officer, 2=leader
/*0194*/ uint8 unknown0194[3];
/*0197*/ union
{
struct
{
/*0197*/ uint32 equip_helmet; // Equipment: Helmet Visual
/*0201*/ uint32 equip_chest; // Equipment: Chest Visual
/*0205*/ uint32 equip_arms; // Equipment: Arms Visual
/*0209*/ uint32 equip_bracers; // Equipment: Bracers Visual
/*0213*/ uint32 equip_hands; // Equipment: Hands Visual
/*0217*/ uint32 equip_legs; // Equipment: Legs Visual
/*0221*/ uint32 equip_feet; // Equipment: Feet Visual
/*0225*/ uint32 equip_primary; // Equipment: Primary Visual
/*0229*/ uint32 equip_secondary; // Equipment: Secondary Visual
} equip;
/*0197*/ uint32 equipment[9]; // Array elements correspond to struct equipment above
};
/*0197*/ TextureProfile equipment;
/*0233*/ float runspeed; // Speed when running
/*0036*/ uint8 afk; // 0=no, 1=afk
/*0238*/ uint32 guildID; // Current guild
@@ -284,22 +311,7 @@ union
};
/*0340*/ uint32 spawnId; // Spawn Id
/*0344*/ uint8 unknown0344[4];
/*0348*/ union
{
struct
{
/*0348*/ Color_Struct color_helmet; // Color of helmet item
/*0352*/ Color_Struct color_chest; // Color of chest item
/*0356*/ Color_Struct color_arms; // Color of arms item
/*0360*/ Color_Struct color_bracers; // Color of bracers item
/*0364*/ Color_Struct color_hands; // Color of hands item
/*0368*/ Color_Struct color_legs; // Color of legs item
/*0372*/ Color_Struct color_feet; // Color of feet item
/*0376*/ Color_Struct color_primary; // Color of primary item
/*0380*/ Color_Struct color_secondary; // Color of secondary item
} equipment_colors;
/*0348*/ Color_Struct colors[9]; // Array elements correspond to struct equipment_colors above
};
/*0348*/ TintProfile equipment_tint;
/*0384*/ uint8 lfg; // 0=off, 1=lfg on
/*0385*/
@@ -378,7 +390,7 @@ struct MemorizeSpell_Struct {
uint32 slot; // Spot in the spell book/memorized slot
uint32 spell_id; // Spell id (200 or c8 is minor healing, etc)
uint32 scribing; // 1 if memorizing a spell, set to 0 if scribing to book, 2 if un-memming
uint32 unknown12;
uint32 reduction; // lowers reuse
};
/*
@@ -408,13 +420,13 @@ struct DeleteSpell_Struct
/*005*/uint8 unknowndss006[3];
/*008*/
};
struct ManaChange_Struct
{
uint32 new_mana; // New Mana AMount
uint32 stamina;
uint32 spell_id;
uint32 unknown12;
/*00*/ uint32 new_mana; // New Mana AMount
/*04*/ uint32 stamina;
/*08*/ uint32 spell_id;
/*12*/ uint8 keepcasting; // won't stop the cast. Change mana while casting?
/*13*/ uint8 padding[3]; // client doesn't read it, garbage data seems like
};
struct SwapSpell_Struct
@@ -461,26 +473,19 @@ struct SpawnAppearance_Struct
// this is used inside profile
struct SpellBuff_Struct
{
/*000*/ uint8 slotid; //badly named... seems to be 2 for a real buff, 0 otherwise
/*000*/ uint8 effect_type; // 0 = no buff, 2 = buff, 4 = inverse affects of buff
/*001*/ uint8 level;
/*002*/ uint8 bard_modifier;
/*003*/ uint8 effect; //not real
/*003*/ uint8 unknown003; // MQ2 used to call this "damage shield" -- don't see client referencing it, so maybe server side DS type tracking?
/*004*/ uint32 spellid;
/*008*/ int32 duration;
/*012*/ uint32 counters;
/*016*/ uint32 player_id; //'global' ID of the caster, for wearoff messages
/*012*/ uint32 counters; // single book keeping value (counters, rune/vie)
/*016*/ uint32 player_id; // caster ID, pretty sure just zone ID
};
struct SpellBuffFade_Struct {
struct SpellBuffPacket_Struct {
/*000*/ uint32 entityid;
/*004*/ uint8 slot;
/*005*/ uint8 level;
/*006*/ uint8 effect;
/*007*/ uint8 unknown7;
/*008*/ uint32 spellid;
/*012*/ int32 duration;
/*016*/ uint32 unknown016;
/*020*/ uint32 unknown020; //prolly global player ID
/*004*/ SpellBuff_Struct buff;
/*024*/ uint32 slotid;
/*028*/ uint32 bufffade;
/*032*/
@@ -810,9 +815,9 @@ struct PlayerProfile_Struct
/*00176*/ uint8 hairstyle; // Player hair style
/*00177*/ uint8 beard; // Player beard type
/*00178*/ uint8 unknown00178[10];
/*00188*/ uint32 item_material[9]; // Item texture/material of worn items
/*00188*/ TextureProfile item_material; // Item texture/material of worn items
/*00224*/ uint8 unknown00224[44];
/*00268*/ Color_Struct item_tint[9]; // RR GG BB 00
/*00268*/ TintProfile item_tint; // RR GG BB 00
/*00304*/ AA_Array aa_array[MAX_PP_AA_ARRAY]; // AAs
/*02224*/ uint32 points; // Unspent Practice points
/*02228*/ uint32 mana; // Current mana
@@ -1035,7 +1040,7 @@ struct SpecialMesg_Struct
struct WearChange_Struct{
/*000*/ uint16 spawn_id;
/*002*/ uint16 material;
/*004*/ Color_Struct color;
/*004*/ Tint_Struct color;
/*009*/ uint8 wear_slot_id;
};
@@ -1652,8 +1657,7 @@ struct Merchant_Sell_Struct {
/*004*/ uint32 playerid; // Player's entity id
/*008*/ uint32 itemslot;
uint32 unknown12;
/*016*/ uint8 quantity; // Already sold
/*017*/ uint8 Unknown016[3];
/*016*/ uint32 quantity;
/*020*/ uint32 price;
};
struct Merchant_Purchase_Struct {
@@ -2591,27 +2595,6 @@ struct PetitionBug_Struct{
char text[1028];
};
struct DyeStruct
{
union
{
struct
{
struct Color_Struct head;
struct Color_Struct chest;
struct Color_Struct arms;
struct Color_Struct wrists;
struct Color_Struct hands;
struct Color_Struct legs;
struct Color_Struct feet;
struct Color_Struct primary; // you can't actually dye this
struct Color_Struct secondary; // or this
}
dyes;
struct Color_Struct dye[9];
};
};
struct ApproveZone_Struct {
char name[64];
uint32 zoneid;
@@ -3245,6 +3228,11 @@ struct AnnoyingZoneUnknown_Struct {
uint32 value; //always 4
};
struct LoadSpellSet_Struct {
uint32 spell[MAX_PP_MEMSPELL];
uint32 unknown;
};
struct ApplyPoison_Struct {
uint32 inventorySlot;
uint32 success;
+152 -68
View File
@@ -59,6 +59,9 @@ namespace UF
// client to server text link converter
static inline void UFToServerTextLink(std::string& serverTextLink, const std::string& ufTextLink);
static inline CastingSlot ServerToUFCastingSlot(EQEmu::CastingSlot slot);
static inline EQEmu::CastingSlot UFToServerCastingSlot(CastingSlot slot);
void Register(EQStreamIdentifier &into)
{
//create our opcode manager if we havent already
@@ -363,20 +366,29 @@ namespace UF
ENCODE(OP_Buff)
{
ENCODE_LENGTH_EXACT(SpellBuffFade_Struct);
SETUP_DIRECT_ENCODE(SpellBuffFade_Struct, structs::SpellBuffFade_Struct_Underfoot);
ENCODE_LENGTH_EXACT(SpellBuffPacket_Struct);
SETUP_DIRECT_ENCODE(SpellBuffPacket_Struct, structs::SpellBuffPacket_Struct);
OUT(entityid);
OUT(slot);
OUT(level);
OUT(effect);
//eq->unknown7 = 10;
OUT(spellid);
OUT(duration);
OUT(slotid);
OUT(buff.effect_type);
OUT(buff.level);
// just so we're 100% sure we get a 1.0f ...
eq->buff.bard_modifier = emu->buff.bard_modifier == 10 ? 1.0f : emu->buff.bard_modifier / 10.0f;
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 = buffslot;
OUT(bufffade); // Live (October 2011) sends a 2 rather than 0 when a buff is created, but it doesn't seem to matter.
OUT(num_hits);
eq->unknown008 = 1.0f;
FINISH_ENCODE();
}
@@ -398,13 +410,11 @@ namespace UF
for (uint16 i = 0; i < emu->count; ++i)
{
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;
if (emu->type == 0) { // only correct for self packets
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);
@@ -865,8 +875,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, 0); //X tilt
VARSTRUCT_ENCODE_TYPE(float, OutBuffer, 0); //Y tilt
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, 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);
@@ -1374,7 +1384,8 @@ namespace UF
OUT(new_mana);
OUT(stamina);
OUT(spell_id);
eq->unknown16 = -1; // Self Interrupt/Success = -1, Fizzle = 1, Other Interrupt = 2?
OUT(keepcasting);
eq->slot = -1; // this is spell gem slot. It's -1 in normal operation
FINISH_ENCODE();
}
@@ -1752,18 +1763,18 @@ namespace UF
VARSTRUCT_ENCODE_TYPE(uint8, Buffer, 1);
VARSTRUCT_ENCODE_TYPE(uint16, Buffer, emu->buffcount);
for (unsigned int i = 0; i < BUFF_COUNT; ++i)
for (unsigned int i = 0; i < PET_BUFF_COUNT; ++i)
{
if (emu->spellid[i])
{
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, i);
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, emu->spellid[i]);
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, emu->ticsremaining[i]);
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0);
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0); // numhits
VARSTRUCT_ENCODE_TYPE(uint8, Buffer, 0); // This is a string. Name of the caster of the buff.
}
}
VARSTRUCT_ENCODE_TYPE(uint8, Buffer, emu->buffcount);
VARSTRUCT_ENCODE_TYPE(uint8, Buffer, emu->buffcount); /// I think this is actually some sort of type
delete[] __emu_buffer;
dest->FastQueuePacket(&in, ack_req);
@@ -1806,14 +1817,14 @@ namespace UF
OUT(hairstyle);
OUT(beard);
// OUT(unknown00178[10]);
for (r = 0; r < 9; r++) {
eq->equipment[r].Material = emu->item_material[r];
eq->equipment[r].Unknown1 = 0;
eq->equipment[r].EliteMaterial = 0;
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;
//eq->colors[r].color = emu->colors[r].color;
}
for (r = 0; r < 7; r++) {
OUT(item_tint[r].Color);
OUT(item_tint.Slot[r].Color);
}
// OUT(unknown00224[48]);
//NOTE: new client supports 300 AAs, our internal rep/PP
@@ -1858,26 +1869,26 @@ namespace UF
OUT(thirst_level);
OUT(hunger_level);
//PS this needs to be figured out more; but it was 'good enough'
for (r = 0; r < structs::BUFF_COUNT; r++)
for (r = 0; r < BUFF_COUNT; r++)
{
if (emu->buffs[r].spellid != 0xFFFF && emu->buffs[r].spellid != 0)
{
eq->buffs[r].unknown004 = 0x3f800000;
eq->buffs[r].slotid = 2;
eq->buffs[r].bard_modifier = 1.0f + (emu->buffs[r].bard_modifier - 10) / 10.0f;
eq->buffs[r].effect_type= 2;
eq->buffs[r].player_id = 0x000717fd;
}
else
{
eq->buffs[r].slotid = 0;
eq->buffs[r].effect_type = 0;
eq->buffs[r].bard_modifier = 1.0f;
}
//OUT(buffs[r].slotid);
OUT(buffs[r].effect_type);
OUT(buffs[r].level);
//OUT(buffs[r].bard_modifier);
//OUT(buffs[r].effect);
OUT(buffs[r].unknown003);
OUT(buffs[r].spellid);
OUT(buffs[r].duration);
OUT(buffs[r].counters);
//OUT(buffs[r].player_id);
OUT(buffs[r].num_hits);
OUT(buffs[r].player_id);
}
for (r = 0; r < MAX_PP_DISCIPLINES; r++) {
OUT(disciplines.values[r]);
@@ -2290,11 +2301,11 @@ namespace UF
eq_cse->HairColor = emu_cse->HairColor;
eq_cse->Face = emu_cse->Face;
for (int equip_index = 0; equip_index < EQEmu::legacy::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].EliteMaterial;
eq_cse->Equip[equip_index].Color.Color = emu_cse->Equip[equip_index].Color.Color;
eq_cse->Equip[equip_index].Color = emu_cse->Equip[equip_index].Color;
}
eq_cse->PrimaryIDFile = emu_cse->PrimaryIDFile;
@@ -2858,7 +2869,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::EquipStruct) * 9);
PacketSize -= (sizeof(structs::Texture_Struct) * EQEmu::textures::TextureCount);
if (emu->size == 0)
{
@@ -3057,10 +3068,10 @@ namespace UF
if ((emu->NPC == 0) || (emu->race <= 12) || (emu->race == 128) || (emu->race == 130) || (emu->race == 330) || (emu->race == 522))
{
for (k = 0; k < 9; ++k)
for (k = EQEmu::textures::TextureBegin; k < EQEmu::textures::TextureCount; ++k)
{
{
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, emu->colors[k].Color);
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, emu->equipment_tint.Slot[k].Color);
}
}
}
@@ -3070,19 +3081,19 @@ namespace UF
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0);
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0);
if (emu->equipment[EQEmu::legacy::MaterialPrimary].Material > 99999) {
if (emu->equipment.Primary.Material > 99999) {
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 63);
} else {
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, emu->equipment[EQEmu::legacy::MaterialPrimary].Material);
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, emu->equipment.Primary.Material);
}
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0);
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0);
if (emu->equipment[EQEmu::legacy::MaterialSecondary].Material > 99999) {
if (emu->equipment.Secondary.Material > 99999) {
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 63);
} else {
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, emu->equipment[EQEmu::legacy::MaterialSecondary].Material);
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, emu->equipment.Secondary.Material);
}
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0);
@@ -3091,19 +3102,19 @@ namespace UF
if ((emu->NPC == 0) || (emu->race <= 12) || (emu->race == 128) || (emu->race == 130) || (emu->race == 330) || (emu->race == 522))
{
structs::EquipStruct *Equipment = (structs::EquipStruct *)Buffer;
structs::Texture_Struct *Equipment = (structs::Texture_Struct *)Buffer;
for (k = 0; k < 9; k++) {
if (emu->equipment[k].Material > 99999) {
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[k].Material;
Equipment[k].Material = emu->equipment.Slot[k].Material;
}
Equipment[k].Unknown1 = emu->equipment[k].Unknown1;
Equipment[k].EliteMaterial = emu->equipment[k].EliteMaterial;
Equipment[k].Unknown1 = emu->equipment.Slot[k].Unknown1;
Equipment[k].EliteMaterial = emu->equipment.Slot[k].EliteMaterial;
}
Buffer += (sizeof(structs::EquipStruct) * 9);
Buffer += (sizeof(structs::Texture_Struct) * EQEmu::textures::TextureCount);
}
if (strlen(emu->title))
{
@@ -3216,15 +3227,15 @@ namespace UF
DECODE(OP_Buff)
{
DECODE_LENGTH_EXACT(structs::SpellBuffFade_Struct_Underfoot);
SETUP_DIRECT_DECODE(SpellBuffFade_Struct, structs::SpellBuffFade_Struct_Underfoot);
DECODE_LENGTH_EXACT(structs::SpellBuffPacket_Struct);
SETUP_DIRECT_DECODE(SpellBuffPacket_Struct, structs::SpellBuffPacket_Struct);
IN(entityid);
IN(slot);
IN(level);
IN(effect);
IN(spellid);
IN(duration);
IN(buff.effect_type);
IN(buff.level);
IN(buff.unknown003);
IN(buff.spellid);
IN(buff.duration);
IN(slotid);
IN(bufffade);
@@ -3250,10 +3261,7 @@ namespace UF
DECODE_LENGTH_EXACT(structs::CastSpell_Struct);
SETUP_DIRECT_DECODE(CastSpell_Struct, structs::CastSpell_Struct);
if (eq->slot == 13)
emu->slot = 10;
else
IN(slot);
emu->slot = static_cast<uint32>(UFToServerCastingSlot(static_cast<CastingSlot>(eq->slot)));
IN(spell_id);
emu->inventoryslot = UFToServerSlot(eq->inventoryslot);
@@ -3841,11 +3849,11 @@ namespace UF
void SerializeItem(EQEmu::OutBuffer& ob, const ItemInst *inst, int16 slot_id_in, uint8 depth)
{
const EQEmu::Item_Struct *item = inst->GetUnscaledItem();
const EQEmu::ItemBase *item = inst->GetUnscaledItem();
UF::structs::ItemSerializationHeader hdr;
hdr.stacksize = (inst->IsStackable() ? ((inst->GetCharges() > 254) ? 0xFFFFFFFF : inst->GetCharges()) : 1);
hdr.stacksize = (inst->IsStackable() ? ((inst->GetCharges() > 1000) ? 0xFFFFFFFF : inst->GetCharges()) : 1);
hdr.unknown004 = 0;
int32 slot_id = ServerToUFSlot(slot_id_in);
@@ -3885,7 +3893,7 @@ namespace UF
int ornamentationAugtype = RuleI(Character, OrnamentationAugmentType);
uint16 ornaIcon = 0;
if (inst->GetOrnamentationAug(ornamentationAugtype)) {
const EQEmu::Item_Struct *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));
@@ -4369,4 +4377,80 @@ namespace UF
}
}
static inline CastingSlot ServerToUFCastingSlot(EQEmu::CastingSlot slot)
{
switch (slot) {
case EQEmu::CastingSlot::Gem1:
return CastingSlot::Gem1;
case EQEmu::CastingSlot::Gem2:
return CastingSlot::Gem2;
case EQEmu::CastingSlot::Gem3:
return CastingSlot::Gem3;
case EQEmu::CastingSlot::Gem4:
return CastingSlot::Gem4;
case EQEmu::CastingSlot::Gem5:
return CastingSlot::Gem5;
case EQEmu::CastingSlot::Gem6:
return CastingSlot::Gem6;
case EQEmu::CastingSlot::Gem7:
return CastingSlot::Gem7;
case EQEmu::CastingSlot::Gem8:
return CastingSlot::Gem8;
case EQEmu::CastingSlot::Gem9:
return CastingSlot::Gem9;
case EQEmu::CastingSlot::Gem10:
return CastingSlot::Gem10;
case EQEmu::CastingSlot::Gem11:
return CastingSlot::Gem11;
case EQEmu::CastingSlot::Gem12:
return CastingSlot::Gem12;
case EQEmu::CastingSlot::Item:
case EQEmu::CastingSlot::PotionBelt:
return CastingSlot::Item;
case EQEmu::CastingSlot::Discipline:
return CastingSlot::Discipline;
case EQEmu::CastingSlot::AltAbility:
return CastingSlot::AltAbility;
default: // we shouldn't have any issues with other slots ... just return something
return CastingSlot::Discipline;
}
}
static inline EQEmu::CastingSlot UFToServerCastingSlot(CastingSlot slot)
{
switch (slot) {
case CastingSlot::Gem1:
return EQEmu::CastingSlot::Gem1;
case CastingSlot::Gem2:
return EQEmu::CastingSlot::Gem2;
case CastingSlot::Gem3:
return EQEmu::CastingSlot::Gem3;
case CastingSlot::Gem4:
return EQEmu::CastingSlot::Gem4;
case CastingSlot::Gem5:
return EQEmu::CastingSlot::Gem5;
case CastingSlot::Gem6:
return EQEmu::CastingSlot::Gem6;
case CastingSlot::Gem7:
return EQEmu::CastingSlot::Gem7;
case CastingSlot::Gem8:
return EQEmu::CastingSlot::Gem8;
case CastingSlot::Gem9:
return EQEmu::CastingSlot::Gem9;
case CastingSlot::Gem10:
return EQEmu::CastingSlot::Gem10;
case CastingSlot::Gem11:
return EQEmu::CastingSlot::Gem11;
case CastingSlot::Gem12:
return EQEmu::CastingSlot::Gem12;
case CastingSlot::Discipline:
return EQEmu::CastingSlot::Discipline;
case CastingSlot::Item:
return EQEmu::CastingSlot::Item;
case CastingSlot::AltAbility:
return EQEmu::CastingSlot::AltAbility;
default: // we shouldn't have any issues with other slots ... just return something
return EQEmu::CastingSlot::Discipline;
}
}
} /*UF*/
+18
View File
@@ -50,6 +50,24 @@ namespace UF
#include "uf_ops.h"
};
enum class CastingSlot : uint32 {
Gem1 = 0,
Gem2 = 1,
Gem3 = 2,
Gem4 = 3,
Gem5 = 4,
Gem6 = 5,
Gem7 = 6,
Gem8 = 7,
Gem9 = 8,
Gem10 = 9,
Gem11 = 10,
Gem12 = 11,
Item = 12,
Discipline = 13,
AltAbility = 0xFF
};
}; /*UF*/
#endif /*COMMON_UF_H*/
+29 -12
View File
@@ -10,7 +10,7 @@
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.
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
@@ -22,7 +22,7 @@
#include "../string_util.h"
size_t UF::invtype::InvTypeSize(int inv_type)
size_t UF::invtype::GetInvTypeSize(int inv_type)
{
switch (inv_type) {
case invtype::InvTypePossessions:
@@ -68,7 +68,7 @@ size_t UF::invtype::InvTypeSize(int inv_type)
}
}
const char* UF::invtype::InvTypeName(int inv_type)
const char* UF::invtype::GetInvTypeName(int inv_type)
{
switch (inv_type) {
case invtype::InvTypeInvalid:
@@ -116,7 +116,24 @@ const char* UF::invtype::InvTypeName(int inv_type)
}
}
const char* UF::invslot::InvPossessionsSlotName(int inv_slot)
bool UF::invtype::IsInvTypePersistent(int inv_type)
{
switch (inv_type) {
case invtype::InvTypePossessions:
case invtype::InvTypeBank:
case invtype::InvTypeSharedBank:
case invtype::InvTypeTrade:
case invtype::InvTypeWorld:
case invtype::InvTypeLimbo:
case invtype::InvTypeTribute:
case invtype::InvTypeGuildTribute:
return true;
default:
return false;
}
}
const char* UF::invslot::GetInvPossessionsSlotName(int inv_slot)
{
switch (inv_slot) {
case invslot::InvSlotInvalid:
@@ -190,9 +207,9 @@ const char* UF::invslot::InvPossessionsSlotName(int inv_slot)
}
}
const char* UF::invslot::InvCorpseSlotName(int inv_slot)
const char* UF::invslot::GetInvCorpseSlotName(int inv_slot)
{
if (!invtype::InvTypeSize(invtype::InvTypeCorpse) || inv_slot == invslot::InvSlotInvalid)
if (!invtype::GetInvTypeSize(invtype::InvTypeCorpse) || inv_slot == invslot::InvSlotInvalid)
return "Invalid Slot";
// needs work
@@ -205,14 +222,14 @@ const char* UF::invslot::InvCorpseSlotName(int inv_slot)
return ret_str.c_str();
}
const char* UF::invslot::InvSlotName(int inv_type, int inv_slot)
const char* UF::invslot::GetInvSlotName(int inv_type, int inv_slot)
{
if (inv_type == invtype::InvTypePossessions)
return invslot::InvPossessionsSlotName(inv_slot);
return invslot::GetInvPossessionsSlotName(inv_slot);
else if (inv_type == invtype::InvTypeCorpse)
return invslot::InvCorpseSlotName(inv_slot);
return invslot::GetInvCorpseSlotName(inv_slot);
size_t type_size = invtype::InvTypeSize(inv_type);
size_t type_size = invtype::GetInvTypeSize(inv_type);
if (!type_size || inv_slot == invslot::InvSlotInvalid)
return "Invalid Slot";
@@ -226,7 +243,7 @@ const char* UF::invslot::InvSlotName(int inv_type, int inv_slot)
return ret_str.c_str();
}
const char* UF::invbag::InvBagIndexName(int bag_index)
const char* UF::invbag::GetInvBagIndexName(int bag_index)
{
if (bag_index == invbag::InvBagInvalid)
return "Invalid Bag";
@@ -240,7 +257,7 @@ const char* UF::invbag::InvBagIndexName(int bag_index)
return ret_str.c_str();
}
const char* UF::invaug::InvAugIndexName(int aug_index)
const char* UF::invaug::GetInvAugIndexName(int aug_index)
{
if (aug_index == invaug::InvAugInvalid)
return "Invalid Augment";
+40 -28
View File
@@ -10,7 +10,7 @@
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.
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
@@ -21,7 +21,7 @@
#define COMMON_UF_LIMITS_H
#include "../types.h"
#include "../client_version.h"
#include "../emu_versions.h"
#include "../skills.h"
@@ -32,8 +32,13 @@ namespace UF
enum : bool { False = false, True = true };
// pre-declarations
namespace inventory {
inline EQEmu::versions::ClientVersion GetInventoryRef() { return EQEmu::versions::ClientVersion::UF; }
} /*inventory*/
namespace invtype {
inline EQEmu::versions::ClientVersion InvTypeRef() { return EQEmu::versions::ClientVersion::UF; }
inline EQEmu::versions::ClientVersion GetInvTypeRef() { return EQEmu::versions::ClientVersion::UF; }
enum : int { InvTypeInvalid = -1, InvTypeBegin };
@@ -63,7 +68,7 @@ namespace UF
} /*invtype*/
namespace invslot {
inline EQEmu::versions::ClientVersion InvSlotRef() { return EQEmu::versions::ClientVersion::UF; }
inline EQEmu::versions::ClientVersion GetInvSlotRef() { return EQEmu::versions::ClientVersion::UF; }
enum : int { InvSlotInvalid = -1, InvSlotBegin };
@@ -114,21 +119,21 @@ namespace UF
} /*invslot*/
namespace invbag {
inline EQEmu::versions::ClientVersion InvBagRef() { return EQEmu::versions::ClientVersion::UF; }
inline EQEmu::versions::ClientVersion GetInvBagRef() { return EQEmu::versions::ClientVersion::UF; }
enum : int { InvBagInvalid = -1, InvBagBegin };
} /*invbag*/
namespace invaug {
inline EQEmu::versions::ClientVersion InvAugRef() { return EQEmu::versions::ClientVersion::UF; }
inline EQEmu::versions::ClientVersion GetInvAugRef() { return EQEmu::versions::ClientVersion::UF; }
enum : int { InvAugInvalid = -1, InvAugBegin };
} /*invaug*/
namespace item {
inline EQEmu::versions::ClientVersion ItemRef() { return EQEmu::versions::ClientVersion::UF; }
inline EQEmu::versions::ClientVersion GetItemRef() { return EQEmu::versions::ClientVersion::UF; }
enum ItemPacketType : int {
ItemPacketMerchant = 100,
@@ -147,27 +152,37 @@ namespace UF
} /*item*/
namespace profile {
inline EQEmu::versions::ClientVersion ProfileRef() { return EQEmu::versions::ClientVersion::UF; }
inline EQEmu::versions::ClientVersion GetProfileRef() { return EQEmu::versions::ClientVersion::UF; }
} /*profile*/
namespace constants {
inline EQEmu::versions::ClientVersion ConstantsRef() { return EQEmu::versions::ClientVersion::UF; }
inline EQEmu::versions::ClientVersion GetConstantsRef() { return EQEmu::versions::ClientVersion::UF; }
} /*constants*/
namespace behavior {
inline EQEmu::versions::ClientVersion BehaviorRef() { return EQEmu::versions::ClientVersion::UF; }
inline EQEmu::versions::ClientVersion GetBehaviorRef() { return EQEmu::versions::ClientVersion::UF; }
} /*behavior*/
namespace skills {
inline EQEmu::versions::ClientVersion SkillsRef() { return EQEmu::versions::ClientVersion::UF; }
inline EQEmu::versions::ClientVersion GetSkillsRef() { return EQEmu::versions::ClientVersion::UF; }
} /*skills*/
// declarations
namespace inventory {
const bool ConcatenateInvTypeLimbo = true;
const bool AllowOverLevelEquipment = true;
const bool AllowEmptyBagInBag = false;
const bool AllowClickCastFromBag = false;
} /*inventory*/
namespace invtype {
const size_t InvTypePossessionsSize = invslot::PossessionsCount;
const size_t InvTypeBankSize = 24;
@@ -176,7 +191,7 @@ namespace UF
const size_t InvTypeWorldSize = 10;
const size_t InvTypeLimboSize = 36;
const size_t InvTypeTributeSize = 5;
const size_t InvTypeGuildTributeSize = 0;//unknown
const size_t InvTypeGuildTributeSize = 2;
const size_t InvTypeMerchantSize = 80;
const size_t InvTypeCorpseSize = InvTypePossessionsSize;
const size_t InvTypeBazaarSize = 80;
@@ -189,10 +204,10 @@ namespace UF
const size_t InvTypeArchivedSize = 0;//unknown
const size_t InvTypeOtherSize = 0;//unknown
const size_t NPCTradeSize = 4;
extern size_t GetInvTypeSize(int inv_type);
extern const char* GetInvTypeName(int inv_type);
extern size_t InvTypeSize(int inv_type);
extern const char* InvTypeName(int inv_type);
extern bool IsInvTypePersistent(int inv_type);
} /*invtype*/
@@ -211,14 +226,17 @@ namespace UF
const int WorldEnd = (WorldBegin + invtype::InvTypeWorldSize) - 1;
const int TributeBegin = 400;
const int TributeEnd = 404;
const int TributeEnd = (TributeBegin + invtype::InvTypeTributeSize) - 1;
const int GuildTributeBegin = 450;
const int GuildTributeEnd = (GuildTributeBegin + invtype::InvTypeGuildTributeSize) - 1;
const int CorpseBegin = invslot::PossessionsGeneral1;
const int CorpseEnd = invslot::PossessionsGeneral1 + invslot::PossessionsCursor;
extern const char* InvPossessionsSlotName(int inv_slot);
extern const char* InvCorpseSlotName(int inv_slot);
extern const char* InvSlotName(int inv_type, int inv_slot);
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*/
@@ -245,14 +263,14 @@ namespace UF
const int TradeBagsSize = invtype::InvTypeTradeSize * ItemBagSize;
const int TradeBagsEnd = (TradeBagsBegin + TradeBagsSize) - 1;
extern const char* InvBagIndexName(int bag_index);
extern const char* GetInvBagIndexName(int bag_index);
} /*invbag*/
namespace invaug {
const size_t ItemAugSize = 5;
extern const char* InvAugIndexName(int aug_index);
extern const char* GetInvAugIndexName(int aug_index);
} /*invaug*/
@@ -262,6 +280,7 @@ namespace UF
namespace profile {
const size_t TributeSize = invtype::InvTypeTributeSize;
const size_t GuildTributeSize = invtype::InvTypeGuildTributeSize;
const size_t BandoliersSize = 20; // number of bandolier instances
const size_t BandolierItemCount = 4; // number of equipment slots in bandolier instance
@@ -280,13 +299,6 @@ namespace UF
} /*constants*/
namespace behavior {
const bool ConcatenateInvTypeLimbo = true;
const bool AllowOverLevelEquipment = true;
const bool AllowEmptyBagInBag = false;
const bool AllowClickCastFromBag = false;
const bool CoinHasWeight = false;
} /*behavior*/
+81 -148
View File
@@ -26,7 +26,7 @@ namespace UF
namespace structs {
static const uint32 BUFF_COUNT = 25;
static const uint32 BUFF_COUNT = 30;
/*
** Compiler override to ensure
@@ -122,27 +122,70 @@ struct AdventureInfo {
** Merth: Gave struct a name so gcc 2.96 would compile
**
*/
struct Color_Struct
struct Tint_Struct
{
union {
struct {
uint8 blue;
uint8 Blue;
uint8 Green;
uint8 Red;
uint8 UseTint; // if there's a tint this is FF
} RGB;
};
uint32 Color;
};
};
struct CharSelectEquip
struct TintProfile
{
union {
struct {
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;
};
Tint_Struct Slot[EQEmu::textures::TextureCount];
};
};
/*
* Visible equiptment.
* Size: 12 Octets
*/
struct Texture_Struct
{
uint32 Material;
uint32 Unknown1;
uint32 EliteMaterial;
Color_Struct Color;
};
struct TextureProfile
{
union {
struct {
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;
};
Texture_Struct Slot[EQEmu::textures::TextureCount];
};
TextureProfile();
};
struct CharSelectEquip : Texture_Struct, Tint_Struct {};
struct CharacterSelectEntry_Struct
{
/*0000*/ uint8 Level; //
@@ -152,7 +195,7 @@ struct CharacterSelectEntry_Struct
/*0000*/ uint8 Beard; //
/*0001*/ uint8 HairColor; //
/*0000*/ uint8 Face; //
/*0000*/ CharSelectEquip Equip[9];
/*0000*/ CharSelectEquip Equip[EQEmu::textures::TextureCount];
/*0000*/ uint32 PrimaryIDFile; //
/*0000*/ uint32 SecondaryIDFile; //
/*0000*/ uint8 Unknown15; // 0xff
@@ -185,19 +228,6 @@ struct CharacterSelect_Struct
/*0008*/ CharacterSelectEntry_Struct Entries[0];
};
/*
* Visible equiptment.
* Size: 12 Octets
*/
struct EquipStruct
{
/*00*/ uint32 Material;
/*04*/ uint32 Unknown1;
/*08*/ uint32 EliteMaterial;
/*12*/
};
/*
** Generic Spawn Struct
** Length: 897 Octets
@@ -314,40 +344,10 @@ struct Spawn_Struct
/*0000*/ uint32 unknown18;
/*0000*/ uint32 unknown19;
Spawn_Struct_Position Position;
/*0000*/ union
{
struct
{
/*0000*/ Color_Struct color_helmet; // Color of helmet item
/*0000*/ Color_Struct color_chest; // Color of chest item
/*0000*/ Color_Struct color_arms; // Color of arms item
/*0000*/ Color_Struct color_bracers; // Color of bracers item
/*0000*/ Color_Struct color_hands; // Color of hands item
/*0000*/ Color_Struct color_legs; // Color of legs item
/*0000*/ Color_Struct color_feet; // Color of feet item
/*0000*/ Color_Struct color_primary; // Color of primary item
/*0000*/ Color_Struct color_secondary; // Color of secondary item
} equipment_colors;
/*0000*/ Color_Struct colors[9]; // Array elements correspond to struct equipment_colors above
};
/*0000*/ TintProfile equipment_tint;
// skip these bytes if not a valid player race
/*0000*/ union
{
struct
{
/*0000*/ EquipStruct equip_helmet; // Equiptment: Helmet visual
/*0000*/ EquipStruct equip_chest; // Equiptment: Chest visual
/*0000*/ EquipStruct equip_arms; // Equiptment: Arms visual
/*0000*/ EquipStruct equip_bracers; // Equiptment: Wrist visual
/*0000*/ EquipStruct equip_hands; // Equiptment: Hands visual
/*0000*/ EquipStruct equip_legs; // Equiptment: Legs visual
/*0000*/ EquipStruct equip_feet; // Equiptment: Boots visual
/*0000*/ EquipStruct equip_primary; // Equiptment: Main visual
/*0000*/ EquipStruct equip_secondary; // Equiptment: Off visual
} equip;
/*0000*/ EquipStruct equipment[9];
};
/*0000*/ TextureProfile equipment;
/*0000*/ //char title[0]; // only read if(hasTitleOrSuffix & 4)
/*0000*/ //char suffix[0]; // only read if(hasTitleOrSuffix & 8)
@@ -479,7 +479,7 @@ struct MemorizeSpell_Struct {
uint32 slot; // Spot in the spell book/memorized slot
uint32 spell_id; // Spell id (200 or c8 is minor healing, etc)
uint32 scribing; // 1 if memorizing a spell, set to 0 if scribing to book, 2 if un-memming
//uint32 unknown12;
uint32 reduction; // lowers reuse
};
/*
@@ -512,11 +512,12 @@ struct DeleteSpell_Struct
struct ManaChange_Struct
{
uint32 new_mana; // New Mana AMount
uint32 stamina;
uint32 spell_id;
uint32 unknown12;
uint32 unknown16;
/*00*/ uint32 new_mana; // New Mana AMount
/*04*/ uint32 stamina;
/*08*/ uint32 spell_id;
/*12*/ uint8 keepcasting; // won't stop the cast. Change mana while casting?
/*13*/ uint8 padding[3]; // client doesn't read it, garbage data seems like
/*16*/ int32 slot; // -1 for normal usage slot for when we want silent interrupt? I think it does timer stuff or something. Linked Spell Reuse interrupt uses it
};
struct SwapSpell_Struct
@@ -566,55 +567,28 @@ struct SpawnAppearance_Struct
// Size 76 (was 24)
struct SpellBuff_Struct
{
/*000*/ uint8 slotid; // badly named... seems to be 2 for a real buff, 0 otherwise
/*001*/ uint8 level;
/*002*/ uint8 bard_modifier;
/*003*/ uint8 effect; // not real
/*004*/ uint32 unknown004; // Seen 1 for no buff
/*008*/ uint32 spellid;
/*012*/ int32 duration;
/*016*/ uint32 unknown016;
/*020*/ uint32 player_id; // 'global' ID of the caster, for wearoff messages
/*024*/ uint32 counters;
/*028*/ uint8 unknown0028[48];
/*076*/
/*000*/ uint8 effect_type; // 0 = no buff, 2 = buff, 4 = inverse affects of buff
/*001*/ uint8 level; // Seen 1 for no buff
/*002*/ uint8 unknown002; //pretty sure padding now
/*003*/ uint8 unknown003; // MQ2 used to call this "damage shield" -- don't see client referencing it, so maybe server side DS type tracking?
/*004*/ float bard_modifier;
/*008*/ uint32 spellid;
/*012*/ uint32 duration;
/*016*/ uint32 num_hits;
/*020*/ uint32 player_id; // caster ID, pretty sure just zone ID
/*024*/ uint32 unknown036;
/*028*/ int32 slot_data[12]; // book keeping stuff per slot (counters, rune/vie)
};
// Not functional yet, but this is what the packet looks like on Underfoot
struct SpellBuffFade_Struct_Underfoot {
struct SpellBuffPacket_Struct {
/*000*/ uint32 entityid; // Player id who cast the buff
/*004*/ uint8 slot;
/*005*/ uint8 level;
/*006*/ uint8 effect;
/*007*/ uint8 unknown7;
/*008*/ float unknown008;
/*012*/ uint32 spellid;
/*016*/ int32 duration;
/*020*/ uint32 num_hits;
/*024*/ uint32 playerId; // Global player ID?
/*028*/ uint32 unknown020;
/*032*/ uint8 unknown0028[48];
/*004*/ SpellBuff_Struct buff;
/*080*/ uint32 slotid;
/*084*/ uint32 bufffade;
/*088*/
};
struct SpellBuffFade_Struct {
/*000*/ uint32 entityid;
/*004*/ uint8 slot;
/*005*/ uint8 level;
/*006*/ uint8 effect;
/*007*/ uint8 unknown7;
/*008*/ uint32 spellid;
/*012*/ int32 duration;
/*016*/ uint32 unknown016;
/*020*/ uint32 unknown020; // Global player ID?
/*024*/ uint32 playerId; // Player id who cast the buff
/*028*/ uint32 slotid;
/*032*/ uint32 bufffade;
/*036*/
};
#if 0
struct BuffIconEntry_Struct {
/*000*/ uint32 buff_slot;
@@ -873,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 = 10; //was 9 now 10 on Underfoot
static const uint32 MAX_PP_MEMSPELL = 12; //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;
@@ -943,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[14]; // Seen 00 00 00 00 00 00 00 00 00 00 00 00 02 01
/*00208*/ uint8 unknown00208[6]; // 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
@@ -952,24 +926,9 @@ struct PlayerProfile_Struct
/*00230*/ uint8 hairstyle; // Player hair style
/*00231*/ uint8 beard; // Player beard type
/*00232*/ uint8 unknown00232[4]; // was 14
/*00236*/ union
{
struct
{
/*00236*/ EquipStruct equip_helmet; // Equiptment: Helmet visual
/*00248*/ EquipStruct equip_chest; // Equiptment: Chest visual
/*00260*/ EquipStruct equip_arms; // Equiptment: Arms visual
/*00272*/ EquipStruct equip_bracers; // Equiptment: Wrist visual
/*00284*/ EquipStruct equip_hands; // Equiptment: Hands visual
/*00296*/ EquipStruct equip_legs; // Equiptment: Legs visual
/*00308*/ EquipStruct equip_feet; // Equiptment: Boots visual
/*00320*/ EquipStruct equip_primary; // Equiptment: Main visual
/*00332*/ EquipStruct equip_secondary; // Equiptment: Off visual
} equip;
/*00236*/ EquipStruct equipment[9]; //Underfoot Shows [108] for this part
};
/*00236*/ TextureProfile equipment;
/*00344*/ uint8 unknown00344[168]; // Underfoot Shows [160]
/*00512*/ Color_Struct item_tint[9]; // RR GG BB 00
/*00512*/ TintProfile item_tint; // RR GG BB 00
/*00548*/ AA_Array aa_array[MAX_PP_AA_ARRAY]; // [3600] AAs 12 bytes each
/*04148*/ uint32 points; // Unspent Practice points - RELOCATED???
/*04152*/ uint32 mana; // Current mana
@@ -986,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[28]; //#### uint8 unknown04396[32]; in Titanium ####[28]
/*07284*/ uint8 unknown07284[20]; //#### 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
@@ -1000,8 +959,7 @@ struct PlayerProfile_Struct
/*07880*/ uint32 toxicity; // Potion Toxicity (15=too toxic, each potion adds 3)
/*07884*/ uint32 thirst_level; // Drink (ticks till next drink)
/*07888*/ uint32 hunger_level; // Food (ticks till next eat)
/*07892*/ SpellBuff_Struct buffs[BUFF_COUNT]; // [1900] Buffs currently on the player (30 Max) - (Each Size 76)
/*09792*/ uint8 unknown09792[380]; // BUFF_COUNT has been left at 25. These are the extra 5 buffs in Underfoot
/*07892*/ SpellBuff_Struct buffs[BUFF_COUNT]; // [2280] Buffs currently on the player (30 Max) - (Each Size 76)
/*10172*/ Disciplines_Struct disciplines; // [400] Known disciplines
/*10972*/ uint32 recastTimers[MAX_RECAST_TYPES]; // Timers (UNIX Time of last use)
/*11052*/ uint8 unknown11052[160]; // Some type of Timers
@@ -1232,7 +1190,7 @@ struct WearChange_Struct{
/*002*/ uint32 material;
/*006*/ uint32 unknown06;
/*010*/ uint32 elite_material; // 1 for Drakkin Elite Material
/*014*/ Color_Struct color;
/*014*/ Tint_Struct color;
/*018*/ uint8 wear_slot_id;
/*019*/
};
@@ -1963,8 +1921,7 @@ struct Merchant_Sell_Struct {
/*004*/ uint32 playerid; // Player's entity id
/*008*/ uint32 itemslot;
/*012*/ uint32 unknown12;
/*016*/ uint8 quantity; // Already sold
/*017*/ uint8 Unknown017[3];
/*016*/ uint32 quantity;
/*020*/ uint32 Unknown020;
/*024*/ uint32 price;
/*028*/ uint32 pricehighorderbits; // It appears the price is 64 bits in Underfoot+
@@ -2054,7 +2011,7 @@ struct AdventureLeaderboard_Struct
/*struct Item_Shop_Struct {
uint16 merchantid;
uint8 itemtype;
Item_Struct item;
ItemBase item;
uint8 iss_unknown001[6];
};*/
@@ -2209,9 +2166,7 @@ struct GroupFollow_Struct { // Underfoot Follow Struct
struct InspectBuffs_Struct {
/*000*/ uint32 spell_id[BUFF_COUNT];
/*100*/ uint32 filler100[5]; // BUFF_COUNT is really 30...
/*120*/ int32 tics_remaining[BUFF_COUNT];
/*220*/ uint32 filler220[5]; // BUFF_COUNT is really 30...
};
@@ -3162,27 +3117,6 @@ struct PetitionBug_Struct{
char text[1028];
};
struct DyeStruct
{
union
{
struct
{
struct Color_Struct head;
struct Color_Struct chest;
struct Color_Struct arms;
struct Color_Struct wrists;
struct Color_Struct hands;
struct Color_Struct legs;
struct Color_Struct feet;
struct Color_Struct primary; // you can't actually dye this
struct Color_Struct secondary; // or this
}
dyes;
struct Color_Struct dye[9];
};
};
struct ApproveZone_Struct {
char name[64];
uint32 zoneid;
@@ -3994,7 +3928,6 @@ 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...
};
+3 -1
View File
@@ -37,10 +37,12 @@ enum { //values for pTimerType
pTimerSenseTraps = 12,
pTimerDisarmTraps = 13,
pTimerDisciplineReuseStart = 14,
pTimerDisciplineReuseEnd = 24,
pTimerDisciplineReuseEnd = 24, // client actually has 20 ids, but still no disc go that high even on live
pTimerCombatAbility = 25,
pTimerCombatAbility2 = 26, // RoF2+ Tiger Claw is unlinked from other monk skills, generic in case other classes ever need it
pTimerBeggingPickPocket = 27,
pTimerLinkedSpellReuseStart = 28,
pTimerLinkedSpellReuseEnd = 48,
pTimerLayHands = 87, //these IDs are used by client too
pTimerHarmTouch = 89, //so dont change them
+1
View File
@@ -45,6 +45,7 @@
#define TIGER 63
#define ELEMENTAL 75
#define ALLIGATOR 91
#define OGGOK_CITIZEN 93
#define EYE_OF_ZOMM 108
#define WOLF_ELEMENTAL 120
#define INVISIBLE_MAN 127
+14 -1
View File
@@ -142,6 +142,11 @@ RULE_INT(Character, InvSnapshotMinRetryM, 30) // Time (in minutes) to re-attempt
RULE_INT(Character, InvSnapshotHistoryD, 30) // Time (in days) to keep snapshot entries
RULE_BOOL(Character, RestrictSpellScribing, false) // Restricts spell scribing to allowable races/classes of spell scroll, if true
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_CATEGORY_END()
RULE_CATEGORY(Mercs)
@@ -203,6 +208,7 @@ 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)
@@ -329,7 +335,7 @@ RULE_INT(Spells, MaxBuffSlotsNPC, 25)
RULE_INT(Spells, MaxSongSlotsNPC, 10)
RULE_INT(Spells, MaxDiscSlotsNPC, 1)
RULE_INT(Spells, MaxTotalSlotsNPC, 36)
RULE_INT(Spells, MaxTotalSlotsPET, 25) // do not set this higher than 25 until the player profile is removed from the blob
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
@@ -379,6 +385,8 @@ RULE_BOOL(Spells, UseAdditiveFocusFromWornSlot, false) // Allows an additive foc
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)
@@ -502,6 +510,8 @@ RULE_BOOL(NPC, LiveLikeEnrage, false) // If set to true then only player control
RULE_BOOL(NPC, EnableMeritBasedFaction, false) // If set to true, faction will given in the same way as experience (solo/group/raid)
RULE_INT(NPC, NPCToNPCAggroTimerMin, 500)
RULE_INT(NPC, NPCToNPCAggroTimerMax, 6000)
RULE_BOOL(NPC, UseClassAsLastName, true) // Uses class archetype as LastName for npcs with none
RULE_BOOL(NPC, NewLevelScaling, true) // Better level scaling, use old if new formulas would break your server
RULE_CATEGORY_END()
RULE_CATEGORY(Aggro)
@@ -517,6 +527,7 @@ RULE_REAL(Aggro, TunnelVisionAggroMod, 0.75) //people not currently the top hate
RULE_INT(Aggro, MaxScalingProcAggro, 400) // Set to -1 for no limit. Maxmimum amount of aggro that HP scaling SPA effect in a proc will add.
RULE_INT(Aggro, IntAggroThreshold, 75) // Int <= this will aggro regardless of level difference.
RULE_BOOL(Aggro, AllowTickPulling, false) // tick pulling is an exploit in an NPC's call for help fixed sometime in 2006 on live
RULE_BOOL(Aggro, UseLevelAggro, true) // Level 18+ and Undead will aggro regardless of level difference. (this will disabled Rule:IntAggroThreshold if set to true)
RULE_CATEGORY_END()
RULE_CATEGORY(TaskSystem)
@@ -531,6 +542,7 @@ RULE_CATEGORY_END()
#ifdef BOTS
RULE_CATEGORY(Bots)
RULE_INT(Bots, AAExpansion, 8) // Bots get AAs through this expansion
RULE_BOOL(Bots, AllowCamelCaseNames, false) // Allows the use of 'MyBot' type names
RULE_INT(Bots, CommandSpellRank, 1) // Filters bot command spells by rank (1, 2 and 3 are valid filters - any other number allows all ranks)
RULE_INT(Bots, CreationLimit, 150) // Number of bots that each account can create
RULE_BOOL(Bots, FinishBuffing, false) // Allow for buffs to complete even if the bot caster is out of mana. Only affects buffing out of combat.
@@ -664,6 +676,7 @@ RULE_CATEGORY_END()
RULE_CATEGORY(Client)
RULE_BOOL(Client, UseLiveFactionMessage, false) // Allows players to see faction adjustments like Live
RULE_BOOL(Client, UseLiveBlockedMessage, false) // Allows players to see faction adjustments like Live
RULE_CATEGORY_END()
#undef RULE_CATEGORY
+80 -80
View File
@@ -1,4 +1,4 @@
/* EQEMu: Everquest Server Emulator
/* EQEMu: Everquest Server Emulator
Copyright (C) 2001-2016 EQEMu Development Team (http://eqemulator.net)
@@ -10,7 +10,7 @@
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.
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
@@ -22,16 +22,64 @@
#include "string_util.h"
#include "item.h"
#include "item_struct.h"
#include "item_base.h"
#include "../zone/zonedb.h"
EQEmu::saylink::SayLinkEngine::SayLinkEngine()
bool EQEmu::saylink::DegenerateLinkBody(SayLinkBody_Struct& say_link_body_struct, const std::string& say_link_body)
{
memset(&say_link_body_struct, 0, sizeof(say_link_body_struct));
if (say_link_body.length() != EQEmu::legacy::TEXT_LINK_BODY_LENGTH)
return false;
say_link_body_struct.unknown_1 = (uint8)strtol(say_link_body.substr(0, 1).c_str(), nullptr, 16);
say_link_body_struct.item_id = (uint32)strtol(say_link_body.substr(1, 5).c_str(), nullptr, 16);
say_link_body_struct.augment_1 = (uint32)strtol(say_link_body.substr(6, 5).c_str(), nullptr, 16);
say_link_body_struct.augment_2 = (uint32)strtol(say_link_body.substr(11, 5).c_str(), nullptr, 16);
say_link_body_struct.augment_3 = (uint32)strtol(say_link_body.substr(16, 5).c_str(), nullptr, 16);
say_link_body_struct.augment_4 = (uint32)strtol(say_link_body.substr(21, 5).c_str(), nullptr, 16);
say_link_body_struct.augment_5 = (uint32)strtol(say_link_body.substr(26, 5).c_str(), nullptr, 16);
say_link_body_struct.augment_6 = (uint32)strtol(say_link_body.substr(31, 5).c_str(), nullptr, 16);
say_link_body_struct.is_evolving = (uint8)strtol(say_link_body.substr(36, 1).c_str(), nullptr, 16);
say_link_body_struct.evolve_group = (uint32)strtol(say_link_body.substr(37, 4).c_str(), nullptr, 16);
say_link_body_struct.evolve_level = (uint8)strtol(say_link_body.substr(41, 2).c_str(), nullptr, 16);
say_link_body_struct.ornament_icon = (uint32)strtol(say_link_body.substr(43, 5).c_str(), nullptr, 16);
say_link_body_struct.hash = (int)strtol(say_link_body.substr(48, 8).c_str(), nullptr, 16);
return true;
}
bool EQEmu::saylink::GenerateLinkBody(std::string& say_link_body, const SayLinkBody_Struct& say_link_body_struct)
{
say_link_body = StringFormat(
"%1X" "%05X" "%05X" "%05X" "%05X" "%05X" "%05X" "%05X" "%1X" "%04X" "%02X" "%05X" "%08X",
(0x0F & say_link_body_struct.unknown_1),
(0x000FFFFF & say_link_body_struct.item_id),
(0x000FFFFF & say_link_body_struct.augment_1),
(0x000FFFFF & say_link_body_struct.augment_2),
(0x000FFFFF & say_link_body_struct.augment_3),
(0x000FFFFF & say_link_body_struct.augment_4),
(0x000FFFFF & say_link_body_struct.augment_5),
(0x000FFFFF & say_link_body_struct.augment_6),
(0x0F & say_link_body_struct.is_evolving),
(0x0000FFFF & say_link_body_struct.evolve_group),
(0xFF & say_link_body_struct.evolve_level),
(0x000FFFFF & say_link_body_struct.ornament_icon),
(0xFFFFFFFF & say_link_body_struct.hash)
);
if (say_link_body.length() != EQEmu::legacy::TEXT_LINK_BODY_LENGTH)
return false;
return true;
}
EQEmu::SayLinkEngine::SayLinkEngine()
{
Reset();
}
std::string EQEmu::saylink::SayLinkEngine::GenerateLink()
std::string EQEmu::SayLinkEngine::GenerateLink()
{
m_Link.clear();
m_LinkBody.clear();
@@ -59,25 +107,25 @@ std::string EQEmu::saylink::SayLinkEngine::GenerateLink()
return m_Link;
}
void EQEmu::saylink::SayLinkEngine::Reset()
void EQEmu::SayLinkEngine::Reset()
{
m_LinkType = SayLinkBlank;
m_LinkType = saylink::SayLinkBlank;
m_ItemData = nullptr;
m_LootData = nullptr;
m_ItemInst = nullptr;
m_Proxy_unknown_1 = NOT_USED;
m_ProxyItemID = NOT_USED;
m_ProxyAugment1ID = NOT_USED;
m_ProxyAugment2ID = NOT_USED;
m_ProxyAugment3ID = NOT_USED;
m_ProxyAugment4ID = NOT_USED;
m_ProxyAugment5ID = NOT_USED;
m_ProxyAugment6ID = NOT_USED;
m_ProxyIsEvolving = NOT_USED;
m_ProxyEvolveGroup = NOT_USED;
m_ProxyEvolveLevel = NOT_USED;
m_ProxyOrnamentIcon = NOT_USED;
m_ProxyHash = NOT_USED;
m_Proxy_unknown_1 = 0;
m_ProxyItemID = 0;
m_ProxyAugment1ID = 0;
m_ProxyAugment2ID = 0;
m_ProxyAugment3ID = 0;
m_ProxyAugment4ID = 0;
m_ProxyAugment5ID = 0;
m_ProxyAugment6ID = 0;
m_ProxyIsEvolving = 0;
m_ProxyEvolveGroup = 0;
m_ProxyEvolveLevel = 0;
m_ProxyOrnamentIcon = 0;
m_ProxyHash = 0;
m_ProxyText = nullptr;
m_TaskUse = false;
m_Link.clear();
@@ -86,7 +134,7 @@ void EQEmu::saylink::SayLinkEngine::Reset()
m_Error = false;
}
void EQEmu::saylink::SayLinkEngine::generate_body()
void EQEmu::SayLinkEngine::generate_body()
{
/*
Current server mask: EQClientRoF2
@@ -99,19 +147,19 @@ void EQEmu::saylink::SayLinkEngine::generate_body()
memset(&m_LinkBodyStruct, 0, sizeof(SayLinkBody_Struct));
const EQEmu::Item_Struct* item_data = nullptr;
const EQEmu::ItemBase* item_data = nullptr;
switch (m_LinkType) {
case SayLinkBlank:
case saylink::SayLinkBlank:
break;
case SayLinkItemData:
case saylink::SayLinkItemData:
if (m_ItemData == nullptr) { break; }
m_LinkBodyStruct.item_id = m_ItemData->ID;
m_LinkBodyStruct.evolve_group = m_ItemData->LoreGroup; // this probably won't work for all items
//m_LinkBodyStruct.evolve_level = m_ItemData->EvolvingLevel;
// TODO: add hash call
break;
case SayLinkLootItem:
case saylink::SayLinkLootItem:
if (m_LootData == nullptr) { break; }
item_data = database.GetItem(m_LootData->item_id);
if (item_data == nullptr) { break; }
@@ -126,7 +174,7 @@ void EQEmu::saylink::SayLinkEngine::generate_body()
//m_LinkBodyStruct.evolve_level = item_data->EvolvingLevel;
// TODO: add hash call
break;
case SayLinkItemInst:
case saylink::SayLinkItemInst:
if (m_ItemInst == nullptr) { break; }
if (m_ItemInst->GetItem() == nullptr) { break; }
m_LinkBodyStruct.item_id = m_ItemInst->GetItem()->ID;
@@ -195,29 +243,29 @@ void EQEmu::saylink::SayLinkEngine::generate_body()
);
}
void EQEmu::saylink::SayLinkEngine::generate_text()
void EQEmu::SayLinkEngine::generate_text()
{
if (m_ProxyText != nullptr) {
m_LinkText = m_ProxyText;
return;
}
const EQEmu::Item_Struct* item_data = nullptr;
const EQEmu::ItemBase* item_data = nullptr;
switch (m_LinkType) {
case SayLinkBlank:
case saylink::SayLinkBlank:
break;
case SayLinkItemData:
case saylink::SayLinkItemData:
if (m_ItemData == nullptr) { break; }
m_LinkText = m_ItemData->Name;
return;
case SayLinkLootItem:
case saylink::SayLinkLootItem:
if (m_LootData == nullptr) { break; }
item_data = database.GetItem(m_LootData->item_id);
if (item_data == nullptr) { break; }
m_LinkText = item_data->Name;
return;
case SayLinkItemInst:
case saylink::SayLinkItemInst:
if (m_ItemInst == nullptr) { break; }
if (m_ItemInst->GetItem() == nullptr) { break; }
m_LinkText = m_ItemInst->GetItem()->Name;
@@ -228,51 +276,3 @@ void EQEmu::saylink::SayLinkEngine::generate_text()
m_LinkText = "null";
}
bool EQEmu::saylink::DegenerateLinkBody(SayLinkBody_Struct& say_link_body_struct, const std::string& say_link_body)
{
memset(&say_link_body_struct, 0, sizeof(say_link_body_struct));
if (say_link_body.length() != EQEmu::legacy::TEXT_LINK_BODY_LENGTH)
return false;
say_link_body_struct.unknown_1 = (uint8)strtol(say_link_body.substr(0, 1).c_str(), nullptr, 16);
say_link_body_struct.item_id = (uint32)strtol(say_link_body.substr(1, 5).c_str(), nullptr, 16);
say_link_body_struct.augment_1 = (uint32)strtol(say_link_body.substr(6, 5).c_str(), nullptr, 16);
say_link_body_struct.augment_2 = (uint32)strtol(say_link_body.substr(11, 5).c_str(), nullptr, 16);
say_link_body_struct.augment_3 = (uint32)strtol(say_link_body.substr(16, 5).c_str(), nullptr, 16);
say_link_body_struct.augment_4 = (uint32)strtol(say_link_body.substr(21, 5).c_str(), nullptr, 16);
say_link_body_struct.augment_5 = (uint32)strtol(say_link_body.substr(26, 5).c_str(), nullptr, 16);
say_link_body_struct.augment_6 = (uint32)strtol(say_link_body.substr(31, 5).c_str(), nullptr, 16);
say_link_body_struct.is_evolving = (uint8)strtol(say_link_body.substr(36, 1).c_str(), nullptr, 16);
say_link_body_struct.evolve_group = (uint32)strtol(say_link_body.substr(37, 4).c_str(), nullptr, 16);
say_link_body_struct.evolve_level = (uint8)strtol(say_link_body.substr(41, 2).c_str(), nullptr, 16);
say_link_body_struct.ornament_icon = (uint32)strtol(say_link_body.substr(43, 5).c_str(), nullptr, 16);
say_link_body_struct.hash = (int)strtol(say_link_body.substr(48, 8).c_str(), nullptr, 16);
return true;
}
bool EQEmu::saylink::GenerateLinkBody(std::string& say_link_body, const SayLinkBody_Struct& say_link_body_struct)
{
say_link_body = StringFormat(
"%1X" "%05X" "%05X" "%05X" "%05X" "%05X" "%05X" "%05X" "%1X" "%04X" "%02X" "%05X" "%08X",
(0x0F & say_link_body_struct.unknown_1),
(0x000FFFFF & say_link_body_struct.item_id),
(0x000FFFFF & say_link_body_struct.augment_1),
(0x000FFFFF & say_link_body_struct.augment_2),
(0x000FFFFF & say_link_body_struct.augment_3),
(0x000FFFFF & say_link_body_struct.augment_4),
(0x000FFFFF & say_link_body_struct.augment_5),
(0x000FFFFF & say_link_body_struct.augment_6),
(0x0F & say_link_body_struct.is_evolving),
(0x0000FFFF & say_link_body_struct.evolve_group),
(0xFF & say_link_body_struct.evolve_level),
(0x000FFFFF & say_link_body_struct.ornament_icon),
(0xFFFFFFFF & say_link_body_struct.hash)
);
if (say_link_body.length() != EQEmu::legacy::TEXT_LINK_BODY_LENGTH)
return false;
return true;
}
+85 -90
View File
@@ -1,4 +1,4 @@
/* EQEMu: Everquest Server Emulator
/* EQEMu: Everquest Server Emulator
Copyright (C) 2001-2016 EQEMu Development Team (http://eqemulator.net)
@@ -10,7 +10,7 @@
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.
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
@@ -28,112 +28,107 @@
struct ServerLootItem_Struct;
class ItemInst;
namespace EQEmu
{
struct Item_Struct;
namespace saylink {
struct SayLinkBody_Struct; // Current server mask: EQClientRoF2
struct ItemBase;
struct SayLinkBody_Struct;
class SayLinkEngine;
namespace saylink {
enum SayLinkType {
SayLinkBlank = 0,
SayLinkItemData,
SayLinkLootItem,
SayLinkItemInst
};
extern bool DegenerateLinkBody(SayLinkBody_Struct& say_Link_body_struct, const std::string& say_link_body);
extern bool GenerateLinkBody(std::string& say_link_body, const SayLinkBody_Struct& say_link_body_struct);
}
}
} /*saylink*/
struct EQEmu::saylink::SayLinkBody_Struct
{
uint8 unknown_1; /* %1X */
uint32 item_id; /* %05X */
uint32 augment_1; /* %05X */
uint32 augment_2; /* %05X */
uint32 augment_3; /* %05X */
uint32 augment_4; /* %05X */
uint32 augment_5; /* %05X */
uint32 augment_6; /* %05X */
uint8 is_evolving; /* %1X */
uint32 evolve_group; /* %05X */
uint8 evolve_level; /* %02X */
uint32 ornament_icon; /* %05X */
int hash; /* %08X */
};
class EQEmu::saylink::SayLinkEngine
{
public:
enum SayLinkType {
SayLinkBlank = 0,
SayLinkItemData,
SayLinkLootItem,
SayLinkItemInst
struct SayLinkBody_Struct {
uint8 unknown_1; /* %1X */
uint32 item_id; /* %05X */
uint32 augment_1; /* %05X */
uint32 augment_2; /* %05X */
uint32 augment_3; /* %05X */
uint32 augment_4; /* %05X */
uint32 augment_5; /* %05X */
uint32 augment_6; /* %05X */
uint8 is_evolving; /* %1X */
uint32 evolve_group; /* %05X */
uint8 evolve_level; /* %02X */
uint32 ornament_icon; /* %05X */
int hash; /* %08X */
};
SayLinkEngine();
class SayLinkEngine {
public:
SayLinkEngine();
void SetLinkType(SayLinkType link_type) { m_LinkType = link_type; }
void SetItemData(const EQEmu::Item_Struct* item_data) { m_ItemData = item_data; }
void SetLootData(const ServerLootItem_Struct* loot_data) { m_LootData = loot_data; }
void SetItemInst(const ItemInst* item_inst) { m_ItemInst = item_inst; }
void SetLinkType(saylink::SayLinkType link_type) { m_LinkType = link_type; }
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 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; }
void SetProxyItemID(uint32 proxy_item_id) { m_ProxyItemID = proxy_item_id; }
void SetProxyAugment1ID(uint32 proxy_augment_id) { m_ProxyAugment1ID = proxy_augment_id; }
void SetProxyAugment2ID(uint32 proxy_augment_id) { m_ProxyAugment2ID = proxy_augment_id; }
void SetProxyAugment3ID(uint32 proxy_augment_id) { m_ProxyAugment3ID = proxy_augment_id; }
void SetProxyAugment4ID(uint32 proxy_augment_id) { m_ProxyAugment4ID = proxy_augment_id; }
void SetProxyAugment5ID(uint32 proxy_augment_id) { m_ProxyAugment5ID = proxy_augment_id; }
void SetProxyAugment6ID(uint32 proxy_augment_id) { m_ProxyAugment6ID = proxy_augment_id; }
void SetProxyIsEvolving(uint8 proxy_is_evolving) { m_ProxyIsEvolving = proxy_is_evolving; }
void SetProxyEvolveGroup(uint32 proxy_evolve_group) { m_ProxyEvolveGroup = proxy_evolve_group; }
void SetProxyEvolveLevel(uint8 proxy_evolve_level) { m_ProxyEvolveLevel = proxy_evolve_level; }
void SetProxyOrnamentIcon(uint32 proxy_ornament_icon) { m_ProxyOrnamentIcon = proxy_ornament_icon; }
void SetProxyHash(int proxy_hash) { m_ProxyHash = proxy_hash; }
// mainly for saylinks..but, not limited to
void SetProxyUnknown1(uint8 proxy_unknown_1) { m_Proxy_unknown_1 = proxy_unknown_1; }
void SetProxyItemID(uint32 proxy_item_id) { m_ProxyItemID = proxy_item_id; }
void SetProxyAugment1ID(uint32 proxy_augment_id) { m_ProxyAugment1ID = proxy_augment_id; }
void SetProxyAugment2ID(uint32 proxy_augment_id) { m_ProxyAugment2ID = proxy_augment_id; }
void SetProxyAugment3ID(uint32 proxy_augment_id) { m_ProxyAugment3ID = proxy_augment_id; }
void SetProxyAugment4ID(uint32 proxy_augment_id) { m_ProxyAugment4ID = proxy_augment_id; }
void SetProxyAugment5ID(uint32 proxy_augment_id) { m_ProxyAugment5ID = proxy_augment_id; }
void SetProxyAugment6ID(uint32 proxy_augment_id) { m_ProxyAugment6ID = proxy_augment_id; }
void SetProxyIsEvolving(uint8 proxy_is_evolving) { m_ProxyIsEvolving = proxy_is_evolving; }
void SetProxyEvolveGroup(uint32 proxy_evolve_group) { m_ProxyEvolveGroup = proxy_evolve_group; }
void SetProxyEvolveLevel(uint8 proxy_evolve_level) { m_ProxyEvolveLevel = proxy_evolve_level; }
void SetProxyOrnamentIcon(uint32 proxy_ornament_icon) { m_ProxyOrnamentIcon = proxy_ornament_icon; }
void SetProxyHash(int proxy_hash) { m_ProxyHash = proxy_hash; }
void SetProxyText(const char* proxy_text) { m_ProxyText = proxy_text; } // overrides standard text use
void SetTaskUse() { m_TaskUse = true; }
void SetProxyText(const char* proxy_text) { m_ProxyText = proxy_text; } // overrides standard text use
void SetTaskUse() { m_TaskUse = true; }
std::string GenerateLink();
bool LinkError() { return m_Error; }
std::string GenerateLink();
bool LinkError() { return m_Error; }
std::string Link() { return m_Link; } // contains full string format: '/12x' '<LinkBody>' '<LinkText>' '/12x'
std::string LinkBody() { return m_LinkBody; } // contains string format: '<LinkBody>'
std::string LinkText() { return m_LinkText; } // contains string format: '<LinkText>'
std::string Link() { return m_Link; } // contains full string format: '/12x' '<LinkBody>' '<LinkText>' '/12x'
std::string LinkBody() { return m_LinkBody; } // contains string format: '<LinkBody>'
std::string LinkText() { return m_LinkText; } // contains string format: '<LinkText>'
void Reset();
void Reset();
private:
void generate_body();
void generate_text();
private:
void generate_body();
void generate_text();
int m_LinkType;
const EQEmu::Item_Struct* m_ItemData;
const ServerLootItem_Struct* m_LootData;
const ItemInst* m_ItemInst;
int m_LinkType;
const ItemBase* m_ItemData;
const ServerLootItem_Struct* m_LootData;
const ItemInst* m_ItemInst;
uint8 m_Proxy_unknown_1;
uint32 m_ProxyItemID;
uint32 m_ProxyAugment1ID;
uint32 m_ProxyAugment2ID;
uint32 m_ProxyAugment3ID;
uint32 m_ProxyAugment4ID;
uint32 m_ProxyAugment5ID;
uint32 m_ProxyAugment6ID;
uint8 m_ProxyIsEvolving;
uint32 m_ProxyEvolveGroup;
uint8 m_ProxyEvolveLevel;
uint32 m_ProxyOrnamentIcon;
int m_ProxyHash;
const char* m_ProxyText;
bool m_TaskUse;
SayLinkBody_Struct m_LinkBodyStruct;
std::string m_Link;
std::string m_LinkBody;
std::string m_LinkText;
bool m_Error;
};
uint8 m_Proxy_unknown_1;
uint32 m_ProxyItemID;
uint32 m_ProxyAugment1ID;
uint32 m_ProxyAugment2ID;
uint32 m_ProxyAugment3ID;
uint32 m_ProxyAugment4ID;
uint32 m_ProxyAugment5ID;
uint32 m_ProxyAugment6ID;
uint8 m_ProxyIsEvolving;
uint32 m_ProxyEvolveGroup;
uint8 m_ProxyEvolveLevel;
uint32 m_ProxyOrnamentIcon;
int m_ProxyHash;
const char* m_ProxyText;
bool m_TaskUse;
SayLinkBody_Struct m_LinkBodyStruct;
std::string m_Link;
std::string m_LinkBody;
std::string m_LinkText;
bool m_Error;
};
} /*EQEmu*/
#endif /*COMMON_SAY_LINK_H*/

Some files were not shown because too many files have changed in this diff Show More