Compare commits

..

297 Commits

Author SHA1 Message Date
KimLS a6675a483d More work to actually make this usable 2015-06-26 01:01:37 -07:00
KimLS 923252dbcc Proof of concept file verification 2015-06-25 18:10:53 -07:00
Michael Cook (mackal) c3a805923c Up the bard level check to 255 again
1-254 actually has special bard logic and client expects it
2015-06-25 13:21:02 -04:00
Michael Cook (mackal) 32e880f571 Identified the extra byte at the end of OP_TargetBuffs/OP_BuffCreate 2015-06-20 14:05:32 -04:00
Michael Cook (mackal) 5481847987 Merge pull request #430 from KinglyKrab/master
Added Combat:BackstabBonus rule.
2015-06-19 20:28:35 -04:00
Kinglykrab 6503e6371a Added Combat:BackstabBonus rule.
- 0 = 0%, 5 = 5%, 50 = 50%, 200 = 200%
2015-06-19 19:55:10 -04:00
Natedog2012 ca311c8990 Merge pull request #429 from KinglyKrab/master
Bot changes.
2015-06-19 13:10:41 -07:00
Kinglykrab c5609db8d1 Preferential bot formatting changes. 2015-06-19 15:53:20 -04:00
Kinglykrab 6ffe7a9563 More bot changes.
- Added #bot showhelm [on|off]
- Allows you to disable your bot's helmet showing up
2015-06-19 05:25:48 -04:00
Kinglykrab 0dcf34d62b Bot changes.
- Added support for Powersource.
- Changed all messages to group messages (Defaults to say if they are not in a group)
2015-06-19 04:46:29 -04:00
Michael Cook (mackal) 08f8e2e55c Fix some RoF2 ops 2015-06-19 01:56:58 -04:00
Michael Cook (mackal) 34655e7753 Merge pull request #428 from KinglyKrab/master
Fixed more possible nullptr related bot crashes.
2015-06-19 01:46:35 -04:00
Kinglykrab 56e064751b Fixed more possible nullptr related bot crashes. 2015-06-19 01:42:01 -04:00
Natedog2012 a583391319 Merge pull request #427 from KinglyKrab/master
Fixed possible bot crashes due to nullptr conflict.
2015-06-18 21:02:33 -07:00
Kinglykrab de81850dd9 Fixed possible bot crashes due to nullptr conflict. 2015-06-18 23:42:59 -04:00
Uleat b1829e929e Updated SessionStats methodology 2015-06-12 19:25:43 -04:00
Michael Cook (mackal) 8dccc8bf90 Fix Pseudo Rooted for runspeed 2015-06-10 23:52:56 -04:00
Michael Cook (mackal) 8174428189 Export SetPseudoRoot to Lua 2015-06-10 23:10:00 -04:00
Michael Cook (mackal) 5186d3a2ef Make filtering out OP_ClientUpdate less aggressive to fix spinning toons
If we are too aggressive filtering out the same position packets it's
possible for toons to continue to spin indefinitely. Instead of
just not sending the update when the position is the same we keep a
tally of how many we get and stop once a threshold (6) is reached.
2015-06-08 18:04:08 -04:00
Michael Cook (mackal) 226bb4f3b2 Fix delete statement 2015-06-08 02:08:32 -04:00
Michael Cook (mackal) 6229b90451 Fix exploit with expendable AAs 2015-06-08 02:00:44 -04:00
Michael Cook (mackal) db307d865b And SQL for last commit 2015-06-07 23:42:28 -04:00
Michael Cook (mackal) 4bb2bb1438 AA packet work mostly and small fix to expendable AAs 2015-06-07 23:41:54 -04:00
Michael Cook (mackal) f198ab714f Make inspect buffs LAA optional for target buffs 2015-06-07 22:31:21 -04:00
Uleat c2e4365214 Implemented rule-based disenchanted bag use 2015-06-07 22:07:40 -04:00
Michael Cook (mackal) 4a036bede2 Merge pull request #426 from clucksoft/expfix
Full group was being excluded from group exp bonus
2015-06-07 20:06:27 -04:00
Russell Kinasz f35594947c Full group was being excluded from group exp bonus 2015-06-07 16:53:38 -07:00
Alex f57734e591 Merge pull request #425 from clucksoft/encounters
More encounter timers support
2015-06-07 15:07:35 -07:00
Michael Cook (mackal) 42a5ddcf77 Cut down on some HP update spam
This increases the timer that mobs will send out updates
(It could probably be increased more)
This will also reset the timer every time SendHPUpdate is called
to prevent sending like 3+ completely useless updates at once
Also skip sending the update to the client if we're sending an
OP_Damage with the damage since the client will apply this number
2015-06-06 17:46:53 -04:00
Michael Cook (mackal) 03bc245318 Fix fleeing when zones have map files 2015-06-05 21:30:35 -04:00
Michael Cook (mackal) a9b98ed057 Add 64-bit ntoh/hton functions for Linux
BSD macros aren't tested, but should work. These should already
be defined on Windows.
2015-06-05 19:07:01 -04:00
Russell Kinasz b45f0f9dbc Lua_Encounter doesn't need to expose constructor 2015-06-05 12:57:53 -07:00
Russell Kinasz 6cb1861c91 Update to encounter timers so they can actually work from hooked events 2015-06-05 12:32:58 -07:00
Russell Kinasz 0b17dc73f1 Update to encounter timers so they can actually work from hooked events 2015-06-05 12:23:42 -07:00
Alex fafbecb055 Merge pull request #424 from clucksoft/encounters
Encounter timers
2015-06-04 13:44:14 -07:00
Michael Cook (mackal) a5d9faf8ea Allow bard DOTs to get random extra tick
This extra tick business needs to be figured out more ...
bard invul and crescendo songs DO NOT get this extra tick, but DOTs do
2015-06-04 01:02:48 -04:00
Natedog2012 00d258a952 Bot pets will now scale with focus effects. Pets will not scale passed 3x their normal size and stay within 10 levels of their base level unless changed with the rule PetPowerLevelCap 2015-06-03 14:21:38 -07:00
Natedog2012 64caf298fb Only return if the target was a Bot member 2015-06-03 10:18:01 -07:00
Natedog2012 7f30950fdb More group related bot crashes fixed. Bots can now be targeted in the group window and kicked from party. They are also no longer raid_targets when conned. 2015-06-03 10:10:17 -07:00
Russell Kinasz dbd07106d7 Updated zone cmakelists.txt 2015-06-02 17:17:40 -07:00
Russell Kinasz 328b7bb93c Add encounters header to lua_general.cpp 2015-06-02 16:32:42 -07:00
Russell Kinasz c351a9b54f Removed unnecessary commented code. 2015-06-02 15:27:57 -07:00
Russell Kinasz 6ff06ded43 Fix for extra_pointers in Encounter methods 2015-06-02 15:21:27 -07:00
Russell Kinasz 2c6fd44811 Implemented encounter timers - no spawn required 2015-06-02 12:25:09 -07:00
Akkadius 66d37cabe4 Merge pull request #423 from KinglyKrab/master
Added GetGlobal() support for all Mobs.
2015-06-01 22:58:14 -05:00
Kinglykrab 9a5ff58213 Added GetGlobal() support for all Mobs.
- Uses memory (no database hits)
- Allows entity-based quest global checks
2015-06-01 22:25:02 -04:00
Michael Cook (mackal) c3c6d18979 Fix RoF+ AA clientver bug 2015-06-01 16:02:55 -04:00
Michael Cook (mackal) aacd288ad7 Update comment [skip ci] 2015-06-01 15:47:04 -04:00
Michael Cook (mackal) 46dd1511af Fix DoBuffTic crash 2015-06-01 14:15:45 -04:00
Michael Cook (mackal) 7011395d4c Pet target in UF+
I think older clients might have something like this that sets
some spawn data, but these are the only clients that display something
2015-05-31 00:09:59 -04:00
Michael Cook (mackal) 03c006bef5 Implement ST_AEClientV1
This should at least be as correct as ST_AEBard is, unsure of the differences
2015-05-30 15:43:16 -04:00
Michael Cook (mackal) bfb40f6c5f Add failure messages for RNG focus 2015-05-30 03:08:02 -04:00
Michael Cook (mackal) 38cdea7d7e Furious Bash focus message 2015-05-30 02:57:03 -04:00
Michael Cook (mackal) d9cab4820a More focus messages 2015-05-29 21:16:30 -04:00
Michael Cook (mackal) 96264cb688 Send the BEGIN_TO_GLOW message after OP_BeginCast when casting a clicky 2015-05-29 15:26:32 -04:00
Michael Cook (mackal) b0d85e3558 More focus messages thanks to Google 2015-05-29 14:55:32 -04:00
Michael Cook (mackal) 0348c0817d Make ResistSpell aware of the level_override nerf 2015-05-29 14:39:09 -04:00
Michael Cook (mackal) a41fd122bc Add PetType petNone so IsCharmed stops lying 2015-05-29 13:18:04 -04:00
Michael Cook (mackal) 8646791d1d Proc buffs like the shissar rogue poisons have a level override
This corrects the level in those cases. Probably should
propagate the level overrides a bit more, but this fixes the
main issues right now.
2015-05-29 03:26:35 -04:00
Michael Cook (mackal) 070183789b More focus messages 2015-05-29 01:58:38 -04:00
Michael Cook (mackal) 36de3879f8 There is a variety to focus messages
I'm not 100% sure these are classic, but Tit+ at least.
I was able to verify these messages -- crap ton more though.
2015-05-29 00:40:34 -04:00
Uleat e588af2e79 Merge pull request #419 from EQEmu/app_pack_fix
Application packet size fix for high byte opcodes (fix #418)
2015-05-28 18:49:08 -04:00
Michael Cook (mackal) 2416960818 Merge pull request #420 from regneq/master
readded previous commit smoother pathing.
2015-05-28 18:41:36 -04:00
regneq be210950d7 readded previous commit smoother pathing. 2015-05-28 15:05:45 -07:00
Michael Cook (mackal) 5917052a6d I guess short duration buffs needed the extra tick 2015-05-28 18:00:25 -04:00
Natedog2012 d7b9d7c990 Forgot the Regen caps oops! 2015-05-28 14:09:14 -07:00
Natedog2012 235d6b6c48 Bots will not benefit from heroic stats, focus effects like a client 2015-05-28 13:58:17 -07:00
Natedog2012 95243fd6ce Modified ZippZipp's bot name fix from the forums. Limited bot name length to fix a crash. Added Filter check too if you use the Name Filter. 2015-05-28 11:48:03 -07:00
Natedog2012 e5f979665d Merge branch 'master' of https://github.com/EQEmu/Server 2015-05-28 11:27:59 -07:00
Natedog2012 22ef16947c Bots will no longer crash when disbanding on death or normal disbanding.. HP values on bots will no longer roll over when checking STAMINA 2015-05-28 11:27:03 -07:00
Michael Cook (mackal) dbbae0e735 Crash for no zonemap 2015-05-28 13:26:55 -04:00
Uleat 24917257e6 Application packet size fix for high byte opcodes 2015-05-27 22:24:00 -04:00
Uleat dbd615572c Revert "Fix for character select screen client crashes (fix #418)"
This reverts commit 92c756c820.
2015-05-26 21:19:48 -04:00
Uleat 92c756c820 Fix for character select screen client crashes (fix #418) 2015-05-26 15:51:18 -04:00
SecretsOTheP 76d7fe1586 Fixes for mobs on pause waypoints dancing around.
Fixes for runspeed <= 0 as reported by demonstar55
2015-05-26 02:27:48 -04:00
SecretsOTheP 4424afac94 Merge branch 'master' of https://github.com/EQEmu/Server 2015-05-26 01:20:06 -04:00
SecretsOTheP 2b495cea5a bot fixes for compiling 2015-05-26 01:19:49 -04:00
Michael Cook (mackal) e7902342dd EQ seems to round the ticks weird ...
A few examples in the comments ...
2015-05-26 00:59:48 -04:00
Akkadius 5c194c7087 Some syntax adjustments to eqtime.cpp [skip ci] 2015-05-25 23:57:48 -05:00
Akkadius b6091c1960 Update changelog descriptor cause prob not clear enough [skip ci] 2015-05-25 23:51:23 -05:00
Akkadius d2a1fb7acf Add file 2015_05_25_npc_types_texture_fields.sql 2015-05-25 23:49:11 -05:00
Akkadius ee136881c8 Implemented disjointed zone based time, this can be triggered via quest methods
Added parameter to LUA and Perl method settime(hour, minute, [update_world = true])
	- If update_world is false, the zone will then unsubscribe itself from regular worldserver time synchronizations
Added DB ver 9082 with update to add npc_types texture columns if table does not currently have them
2015-05-25 23:48:11 -05:00
Michael Cook (mackal) b06e1c2041 Merge pull request #417 from EQEmu/revert-416-master
Revert "Making $npc->RemoveFromHateList actually work"
2015-05-25 13:20:50 -04:00
Michael Cook (mackal) 41ca23eb7c Revert "Making $npc->RemoveFromHateList actually work" 2015-05-25 13:20:26 -04:00
SecretsOTheP 5c4389effb Revert custom changes that came with my code load 2015-05-25 12:39:36 -04:00
SecretsOTheP 788959a5e2 Haynar's movement fixes.
Changes Speed from float to int. EQ client deals with int step locs better than it does floats according to Haynar's testing.

This also contains mob runspeed changes. I recommend you set runspeeds to start in the DB 1.25 for NPCs below 1.25 which will match player runspeeds almost equally. Existing DBs will need to be updated.

General Cleanup of MobAI functions. Mobs now change their heading on AIMovement timers if their targets' heading has changed since that time. This prevents players from being able to land backstabs inbetween mob swings.

Charmed/feared players now send the appropriate packet, there was a missing CastToClient() in spells that was missing.

Mob runspeed can no longer be snared to 0%, instead, 1% of their base runspeed is the maximum. Roots apply as roots instead of a modifier under this code.

There is going to be bugs with this code. It's better we push through it than revert it. Sanctuary has been running this for a good week and we've worked through the issues.

Misc updates:
Exported some variables to perl, including:

EVENT_ITE_CLICK_CAST:
EVENT_ITEM_CLICK:
spell_id - returns the spell_id of the click effect.
return value - cancels the cast.

EVENT_DROP_ITEM:
quantity - returns the # of items dropped in the packet. If the item has charges, charges are returned here instead.
itemname - name of the item being dropped
itemid - id of the item being droppped
spell_id - spell_id associated with the item's click effect.
slotid - the inventory slot id of the item being dropped.
return value - cancels the item from being dropped.

Added Perl function: CalcEXP. Calculates the experience you would gain for an NPC that cons a specific con value to you.

Fixed a bug where you would receive the group experience bonus and group experience messages for simply being in a group, regardless of the player being in the same zone as you.
2015-05-25 12:35:53 -04:00
JJ aaca6fd2d9 Merge pull request #416 from hateborne/master
Making $npc->RemoveFromHateList actually work
2015-05-25 11:20:37 -04:00
hateborne 1bcb5c72a5 Making $npc->RemoveFromHateList actually work
$npc->RemoveFromHateList is a mob function, not an NPC function. Casting
to Mob to let it work.
2015-05-25 10:44:15 -04:00
Michael Cook (mackal) 249d67a1c3 Bards get a bonus tic at some point
Not sure what level but it's between 53 and 85 ...
(although I remember reading something about around 60)

I also didn't notice any of the odd effects the comments speak of ...
I suspect they were fighting each other?
2015-05-25 02:01:51 -04:00
Michael Cook (mackal) 85bdcf413b Bard songs go negative for some reason?
Hot fix for now, I don't think they really need to be extended,
but I need to investigate more.
2015-05-24 18:50:33 -04:00
Uleat 93942fa82b Merge branch 'master' of https://github.com/EQEmu/Server 2015-05-23 18:59:14 -04:00
Uleat 8922c72452 Added a name block memset to the server character select code and a few comments to the OP_CharInfo encodes 2015-05-23 18:59:03 -04:00
KimLS ec8e7139ec errant else statements 2015-05-23 15:54:33 -07:00
KimLS a882397eb6 errant semi-colon, doesn't matter but still 2015-05-23 15:53:56 -07:00
KimLS 7d61934ce6 Add db manifest for dbstr_us.txt stuff 2015-05-23 15:52:42 -07:00
KimLS 7041db7480 Adding dbstr_us.txt support to client files 2015-05-23 15:50:58 -07:00
Michael Cook (mackal) 70048eb6e1 SE_IllusionPersistence affects self only 2015-05-23 17:45:51 -04:00
Michael Cook (mackal) a46b1ac18b Need to actually copy the bard mod too! 2015-05-23 17:36:05 -04:00
Michael Cook (mackal) 00721f4a96 Fix pet instrument mod issue 2015-05-23 17:14:08 -04:00
Michael Cook (mackal) 8aadc36320 Rework buff duration formulas
These are derived from the client

SE_IllusionPresistence will also set the duration to 10k tics like live
2015-05-23 02:20:36 -04:00
Uleat 351e63ae72 Possible fix for some 'random' character select crashes 2015-05-22 19:15:51 -04:00
Michael Cook (mackal) 9cbda0f81b Unlink Tiger Claw from other monk skills for RoF2+
Tiger Claw has its own reuse now, which the client expects

pTimerCombatAbility2 should be able to be used if they do something
similar for other classes.
2015-05-21 18:15:34 -04:00
Michael Cook (mackal) ea44b4b3b1 Fix manifest 2015-05-21 17:25:59 -04:00
Michael Cook (mackal) ea5a1dd6f1 Bard instrument mods should be more consistent with live
Changes:
	Mods are now saved for in the DB so they are loaded on zone
	This allows long duration buffs from bards that get mods to keep their mods
	Ex. Selo's, Symphony of Battle

	Instrument mods are applied to basically anything that is an instrument skill
	The only exception to this is discs (ex. Puretone is Singing but always 10)

	Singing spells from procs (Ex. Storm Blade) that are instrument skills should
	inherit their buffs instrument mod. Doom effects should also. This isn't
	implemented yet.
2015-05-20 02:01:43 -04:00
KimLS 2ef0fc9342 Change to fishing water location algorithim 2015-05-18 21:46:19 -07:00
Alex 02c3fd0905 Merge pull request #414 from hateborne/master
GM Output for Casting Blocked Spells via Logging System
2015-05-18 21:45:07 -07:00
Uleat 4266f45295 Added merc pointer initialization to avoid an invalid pointer condition 2015-05-18 20:40:57 -04:00
Michael Cook (mackal) 553b7c9f8c Move the extra appearance packet guard to SetAppearance 2015-05-18 00:04:55 -04:00
Michael Cook (mackal) 79a87fac1d Guard against eaStanding spam 2015-05-17 23:51:24 -04:00
Uleat 2308d3e880 Fix for EntityList::CheckSpawnQueue() debug assertion failure crash 2015-05-15 22:49:59 -04:00
hateborne cbcaead8df GM Output for Casting Blocked Spells
Utilizing the logging system to display an alert when a GM casts a
blocked spell, giving some notification instead of silent successes on
cast.
2015-05-13 18:41:18 -04:00
Alex 4b7871a665 Merge pull request #411 from regneq/master
smoother NPC pathing. (credit to Haynar from EQMacEmu)
2015-05-11 22:52:13 -07:00
regneq 052f343e4d smoother NPC pathing. (credit to Haynar from EQMacEmu) 2015-05-11 21:42:48 -07:00
Michael Cook (mackal) e6f6da7845 Merge pull request #410 from regneq/master
* change the kill faction hits display before the xp message not after.
2015-05-11 21:49:44 -04:00
regneq cc2a60feb2 * change the kill faction hits display before the xp message not after.
* removed the double level gain messages to display once either the level gained or the level.
* implement the message "You will now lose experience when you die" and "Your items will no longer stay with you..." when reach a certain level already sets in the rule table.
2015-05-11 16:34:46 -07:00
Michael Cook (mackal) d5eeaf4f47 Merge pull request #409 from regneq/master
Fully implemented QuestReward.  (credit to Cavedude on EQMacEmu)
2015-05-11 16:57:53 -04:00
regneq 6fad93aeee QuestReward now accepts a single bool (true or false) for faction instead of 2 int32s. If true, it will pull the faction hits assigned to the NPC in the DB (reversed, of course) and give you that as part of the reward.
Example usage:
e.other:QuestReward(e.self,copper,silver,gold,platinum,itemid,exp,faction)

(Credit to Cavedude)
2015-05-11 12:42:13 -07:00
regneq d1fbd086d7 Fully implemented QuestReward. (credit to Cavedude on EQMacEmu)
Syntax on NPC is:
e.other:QuestReward(e.self,copper,silver,gold,platinum,item,experience,factionid,factionvalue);

This will give you any or all of the rewards and their messages with one call, including the quest ding sound. Any item is sent to your inventory, like SummonItem does now. The coin message is generated by the client, and will give you a message for each coin type (You recieve 5 copper...). No way around that, but it's still useful if the reward only calls for a single type.
2015-05-11 11:35:54 -07:00
Michael Cook (mackal) c360aa9b0f Make use of Aggressive/Weapon PlayerStates
I HAVE NO IDEA WHAT THIS DOES, BUT LIVE DOES IT

Something to do with the animation system, all I know
2015-05-08 22:42:45 -04:00
JJ f68952c168 Update to some spell duration formulas (Shendare).
Filename fixes.
2015-05-08 22:23:50 -04:00
Michael Cook (mackal) bf4ff03641 Use PlayerState to generate stun particles 2015-05-08 00:59:38 -04:00
Michael Cook (mackal) 103d808925 Whoops, we do want to ignore the sender 2015-05-07 22:15:43 -04:00
Michael Cook (mackal) 53a139256d Merge pull request #408 from hateborne/master
Exporting ConnectNodeToNode and AddNode (from Pathing) to Perl
2015-05-07 18:39:27 -04:00
Michael Cook (mackal) 7bcfaf60ab Save PlayerState server side
We now send the PlayerState in the spawn struct to allow clients
to see other bard animations with instrument to be played if they
zone in after the bard equipped the instrument

OP_WeaponEquip2 and OP_WeaponUnequip2 renamed to OP_PlayerStateAdd
and OP_PlayerStateRemove

Still needs work: Get AI controlled mobs sending the correct
PlayerStates. (stunned, attacking, etc)
2015-05-07 18:34:19 -04:00
hateborne ebe2ea697e Exporting ConnectNodeToNode and AddNode (from Pathing) to Perl
Exporting ConnectNodeToNode and AddNode from pathing to Perl so devs can
more quickly build grids with Perl script(s).
2015-05-07 16:06:06 -04:00
Michael Cook (mackal) 8224a9e776 Fix bards not playing their instruments
This is a rather naive implementation, we should really save the
PlayerState server side so we can have newly zoned in clients
after the equip happened to see the animation. But until we find
all the places the PlayerState is sent, this is fine.
2015-05-06 23:40:01 -04:00
Alex be0507c4d3 Merge pull request #407 from noudess/master
The mob AT_Anim (as set in spawn2) was not working in some cases.
2015-05-06 17:30:56 -07:00
SecretsOTheP cfedf53dc0 *cone of shame* forgot a file 2015-05-06 18:53:41 -04:00
SecretsOTheP 4a4a0c5e8b * -Exported additional entity IDs for dropped items to perl upon EVENT_CLICK_OBJECT (clicker_id) and EVENT_PLAYER_PICKUP ($picked_up_entity_id)
-Identified Size / SolidType fields in newer clients and properly exported it to EQEmu for use in UF, RoF, RoF2 via perl accessors. (Should work in LUA, no testing was done though for LUA)
-Added a sanity check for size to objects. Any size over 5000.f seems to crash the newer clients' graphical engines and PEQ has some containers filled in with bogus values.
-Added the ability to return a value on perl function EVENT_PLAYER_PICKUP which sends a fake dropped item ID to the client to generate the appropriate client response so the item can stay on the ground and not be 'picked up'. Should also work in LUA, didn't test LUA.
-Renamed unknown008 and unknown010 to size and solidtype respectively for objects.
2015-05-06 18:50:08 -04:00
Paul Coene 77dca484fe The mob AT_Anim (as set in spawn2) was not correctly displaying in
various situations.

First, the set function for mob _appearance optimized sending a message
if the new appearance was equal to the old.  This cann't be done, as
the 1st time the zone runs there is no client when the set function is
called.  If we're combining set/send, as we are, better to always do both.  This fixes several of the cases.

Repop also did not work, as no code was being called reliably to set
appearance and update the client based on code path and various flags.  This is also fixed.
2015-05-06 15:39:36 -04:00
JJ 690274338d Merge pull request #406 from noudess/master
Beginnings of fix to SendBuffDuration.
2015-05-02 10:15:21 -04:00
Paul Coene 59ab7071b7 Beginnings of fix to SendBuffDuration. 2015-05-02 07:00:52 -04:00
Michael Cook (mackal) 1438c1a9c3 Merge pull request #404 from noudess/master
Mobs that were blinded were being included in every use of IsFeared()
2015-05-02 02:59:39 -04:00
Michael Cook (mackal) 72702be820 Merge pull request #405 from gpanula/master
maxServerID null check (mysql)
2015-05-02 02:58:04 -04:00
GPanula 1ab3cf53e2 if ServerID is null, it will crash the loginserver when it tries to add the new server to tblWorldServerRegistration table 2015-05-01 22:53:36 -05:00
gpanula 79928c190b Merge pull request #1 from EQEmu/master
sync fork up with source
2015-05-01 22:49:57 -05:00
Paul Coene 6c8dfbdc4d Mobs that were blinded were being included in every use of IsFeared() which
was bad.  Blinded mobs can still cast spells when in melee range.  The
original fear code had no blind rolled into it, I added that.  This was an
overright.  I changed the macro to use bonues and fleemode instead of
looking at curfp.  Testing looks good to me.
2015-05-01 20:40:46 -04:00
Michael Cook (mackal) 1f56c7476e Merge pull request #403 from noudess/master
Fix proc messages for undead proc against non-undead.
2015-05-01 20:27:41 -04:00
Paul Coene eda74e66e0 Fix proc messages for undead proc against non-undead. 2015-05-01 19:22:06 -04:00
Alex 80fd71a406 Merge pull request #402 from noudess/master
Allow Kerran race illusions to be either gender.
2015-05-01 15:44:44 -07:00
Paul Coene 399942f6f4 Allow Kerran race illusions to be either gender. 2015-05-01 07:02:23 -04:00
Alex 3846dc2bbc Merge pull request #401 from noudess/master
Check to make sure we're a client before a CastToClient().
2015-04-30 16:59:39 -07:00
Michael Cook (mackal) 06f4fd49ef Implement mob and client melee push
New rules:
Combat:MeleePush turns melee push on/off
Combat:MeleePushChance is the chance that an NPC will be pushed
Clients are pushed every successful hit, need to verify or disprove this
2015-04-30 19:36:21 -04:00
Paul Coene eea667e22d Check to make sure we're a client before a CastToClient(). Missed this
on first patch.
2015-04-30 09:33:11 -04:00
Alex 8b4d601027 Merge pull request #400 from noudess/master
Now Npcs won't respond to hails if they can't see you.
2015-04-30 06:04:06 -07:00
Paul Coene a1960d4a4a Npcs won't respond to hails if they can't see you. 2015-04-30 08:00:36 -04:00
Alex d7c556c672 Merge pull request #399 from noudess/master
Monk wearing magical gloves can hit creatures that need a magical weapon
2015-04-29 18:55:29 -07:00
Paul Coene 2c4ca77ffc Monk wearing magical gloves can hit creatures that need a magical weapon
when fighting hand to hand.
2015-04-29 19:18:17 -04:00
Alex 7bde00c63b Merge pull request #398 from noudess/master
Noexpend spells like flame lick were expending.
2015-04-29 15:30:53 -07:00
Paul Coene 46d7019909 Spells like flame_lick were not requiring flame lick. Noexpend for
flame lick was not working.

Also fixed a log message with arguments reversed.
2015-04-29 08:26:59 -04:00
Alex 41f3b721d6 Merge pull request #395 from noudess/master
Some illusions and some NPC gear not showing up on zone-in & initial spawn if in zone when it occurs
2015-04-28 16:34:01 -07:00
Alex cafac36bed Merge pull request #397 from gpanula/master
Handle nulls in trusted server lookup(mysql)
2015-04-28 16:33:34 -07:00
Michael Cook (mackal) 0d84ede3d6 Allow /pet attack by mob name to work
ex. /pet attack a_snake
2015-04-26 13:35:36 -04:00
GPanula d7e3a33179 opps, lets use a valid ServeLisTypeID 2015-04-26 09:56:46 -05:00
GPanula c84f56f1f5 Avoid returning nulls when looking up if the server is trusted. Nulls will in the query results will cause the loginserver to crash 2015-04-26 09:43:05 -05:00
JJ 47c9690a32 Don't garble # commands. 2015-04-25 11:46:43 -04:00
JJ de57c94d3e Blocked spell negation fix. 2015-04-23 18:42:17 -04:00
Uleat c974b30192 Probable fix for 'Debug Assertion Failure' in Client::GarbleMessage() 2015-04-22 12:29:35 -04:00
JJ 23dd560a72 Don't delete packet when it is still referenced. Create a new packet instead for deconfliction. 2015-04-20 19:48:52 -04:00
Natedog2012 0eda3efe6a Ignore procs when setting recast timers 2015-04-11 22:49:29 -07:00
Michael Cook (mackal) a4ac2b3831 Added some comments about powersource [skip ci] 2015-04-10 21:23:29 -04:00
Michael Cook (mackal) ea240f7814 Fix sign issue with hate redux spells 2015-04-10 03:06:05 -04:00
JJ 0d4775a9df Adjust to safe_delete packets. 2015-04-07 19:57:36 -04:00
JJ 0321bf72a5 Attempt to catch rare crash in zoneserver process. See http://www.eqemulator.org/forums/showthread.php?t=39549 2015-04-07 10:22:47 -04:00
Michael Cook (mackal) 739a7b6f75 Add decoder for OP_Animation for RoF/RoF2 2015-04-06 21:46:37 -04:00
KimLS 979590db9f Fix for lower than intended drop rates for drop limit loot tables after the min drop changes 2015-04-06 17:42:15 -07:00
Michael Cook (mackal) 7bd185b7b7 Fix RoF+ OP_Animation handling
That's handled in the patch file
2015-04-06 16:13:58 -04:00
Natedog2012 7662eaf983 All animation structs were backwards and poorly named.. RoF+ animations work properly 2015-04-06 03:11:04 -07:00
KimLS 78eb8747aa Merge branch 'master' of github.com:EQEmu/Server 2015-04-04 17:03:42 -07:00
KimLS fc1d6c0676 Fix for mindrop on drop tables sometimes not being fully respected 2015-04-04 17:03:28 -07:00
Natedog2012 7e1c296ecf Fix for RoF2 Bow shoot animation struct was off 2015-04-04 05:04:46 -07:00
Michael Cook (mackal) 51a314fa31 for whatever reason spell based procs generate casting messages 2015-04-02 14:54:11 -04:00
Michael Cook (mackal) b3efd8a817 Quick fix for RoF2 discs showing in song window
This is just a hack until someone does a proper solution
2015-04-02 13:42:47 -04:00
Paul Coene bf93d72a43 Added more changes so mobs armor will appear correctly (pc races only)
when the spawn vie gm command or normally with loot tables that equip.

Refined previous changes that fixed the issue with zoning in and not seeing
previosuly spawned armor by sharing the same module.
2015-04-02 13:25:12 -04:00
Paul Coene 026278504f Merge remote-tracking branch 'upstream/master' 2015-04-01 13:04:39 -04:00
Paul Coene a5872b165f Zoning into a new zone did not properly display PCs with tree/object illusions
and NPCs wearing gear in non-weapon slots.

The illusion thing: Not sure why, but te opcode for BulkZoneSpawn doesn't
display the tree/object illusions.  I did notice that even OP_Illusion gets
rejected by the client if sent before Client_Ready.  Maybe that is why.  The
BULKSpawns cannot be sent that late, I tried moving it in the sequence but
it never did the illusions correctly, at any point.  So, we new new the
single spawn OP code for PCs with those illusions.  This works.

The NPC gear thing.  Same story with BulkZoneSpawn,  Not sure why.  The data
is sent correctly.  So now we update the client zoning in (only them) with
what the NPCs are wearing.  Every othe client already is up to date.
2015-04-01 13:00:38 -04:00
Natedog2012 8bd22e8c38 2nd part to Alternate currency fix forgot to paste this back in 2015-03-29 02:16:23 -07:00
Natedog2012 e304e67cf1 Fix how Alternate Currency Reclaim and Create works if the player has 0 currency available 2015-03-29 01:00:57 -07:00
KimLS b6a01871d8 Fix for another bazaar problem 2015-03-28 23:38:41 -07:00
Alex a569e20110 Merge pull request #388 from iequalshane/master
Enable multiple NPC equipment materials
2015-03-28 23:34:43 -07:00
Alex 75146350fc Merge pull request #393 from noudess/master
Vendor message for rejection based on Deity
2015-03-28 23:34:23 -07:00
KayenEQ 2635d37095 Merge pull request #394 from KayenEQ/Development
sympathetic proc fix
2015-03-29 02:11:49 -04:00
KayenEQ a75f4e70a1 sympathetic proc fix 2015-03-29 02:11:02 -04:00
SecretsOTheP b6cc070633 Identified the Target Ring fields for RoF/RoF2 and added a perl accessor for the last target ring position received from the client.
Usage: $client->GetTargetRingX(), $client->GetTargetRingY(), $client->GetTargetRingZ()
2015-03-29 01:35:24 -04:00
Paul Coene 94d118fdf8 Some vendors would decide not to see based on deity, but messages were
picking the next best reason.  Added a message choice that seemed to make
sense for deity.
2015-03-27 17:12:39 -04:00
JJ 4dcb679c53 Manual merge of #387. 2015-03-27 16:40:02 -04:00
Alex ad9e9ba2d6 Merge pull request #392 from N0ctrnl/master
Added individual tradeskill skillup settings rules
2015-03-27 13:32:06 -07:00
N0ctrnl c4a7acb6d1 Update tradeskills.cpp 2015-03-25 12:04:03 -05:00
N0ctrnl e6835804af Update ruletypes.h 2015-03-25 12:00:14 -05:00
KimLS 9598ce45c9 Merge branch 'master' of github.com:EQEmu/Server 2015-03-24 16:37:25 -07:00
KimLS 9ef4825a72 Fix for gaps in path files during add 2015-03-24 16:37:12 -07:00
KayenEQ eed57ddf97 Merge pull request #391 from KayenEQ/Development
More sympathetic proc fixes
2015-03-24 07:13:58 -04:00
KayenEQ 202c59eb48 More sympathetic proc fixes 2015-03-24 07:13:22 -04:00
KayenEQ f86c6d9c5e Merge pull request #390 from KayenEQ/Development
Fix for sympathetic proc code to allow for it to be properly checked fro...
2015-03-24 01:43:26 -04:00
KayenEQ 340ed6c59d Fix for sympathetic proc code to allow for it to be properly checked from spell buffs. 2015-03-24 01:42:34 -04:00
KimLS 0cf5cca415 Other half of bazaar exploit 2015-03-22 23:18:08 -07:00
KimLS f021ee5491 Fix for traders not correctly setting price 2015-03-22 14:47:45 -07:00
KimLS 6c26bc9c8f Fix for alt currency reclaim exploit and fix for exploit in trader code where price != set price 2015-03-20 13:10:36 -07:00
KayenEQ 93eb727ade Merge pull request #389 from KayenEQ/Development
Fix for pets not receiving group buffs cast on them correctly.
2015-03-19 16:23:23 -04:00
KayenEQ 1c454d9569 Fix for pets not receiving group buffs cast on them correctly. 2015-03-19 16:22:17 -04:00
JJ 3b9f62f0a1 Exported ReloadZoneStaticData to perl and lua.
Usage:
(perl) quest::reloadzonestaticdata();
(lua) eq.reloadzonestaticdata();
2015-03-18 02:49:00 -04:00
Akkadius cd82aae183 [eqemu_update.pl] Small line adjustment [skip ci] 2015-03-12 11:40:46 -05:00
Akkadius d08d50f4b5 [eqemu_update.pl] Set version back to 7... [skip ci] 2015-03-12 11:19:41 -05:00
Akkadius c5fb9ba6dd [eqemu_update.pl] Make it so script is still useable when eqemu_config.xml is not present with no DB configurations [skip ci] 2015-03-12 01:05:25 -05:00
Akkadius 2bcb964326 [eqemu_update.pl V7] Add Option 9) LUA Modules - Download latest LUA Modules (Required for Lua) [skip ci] 2015-03-12 00:33:52 -05:00
Akkadius b3a0370e71 [eqemu_update.pl] Linux compatibility adjustments [skip ci] 2015-03-12 00:08:10 -05:00
Akkadius 9344cfb4e3 [eqemu_update.pl] Add Option 20) to self update script [skip ci] 2015-03-11 21:06:58 -05:00
Akkadius bcf8b1af8e [eqemu_update.pl] Add Option 7) Plugins - Download latest Perl plugins
[eqemu_update.pl] Add Option 8) Quests - Download latest PEQ quests and stage updates
[eqemu_update.pl] Set version 5 of script
[skip ci]
2015-03-11 21:01:43 -05:00
Shane Lynch 2003efb5ab Enable multiple NPC equipment materials (part2)
Adding missing header from previous commit.
2015-03-10 21:59:31 -07:00
Shane Lynch 13743caf19 Enable multiple NPC equipment materials
This change allows #npcedit
armtexture/bracertexture/handtexture/legtexture/feettexture to work
properly and sets individual armor slot materials for NPCs.
2015-03-10 21:33:44 -07:00
Akkadius 6a241d44cc Fix small issue where eqemu_update.pl script would bomb at the very end of the maps download because of blank string [skip ci] 2015-03-10 22:59:07 -05:00
Akkadius b36d9fe115 Update world binary with eqemu_update.pl script version [skip ci] 2015-03-10 22:44:30 -05:00
Akkadius c313bd8d07 Re-rename UF.conf again [skip ci] 2015-03-10 22:40:20 -05:00
Akkadius be9066235b [eqemu_update.pl] Add Option 6) Download Latest map and water files 2015-03-10 22:37:17 -05:00
KayenEQ 1f540666f8 Merge pull request #386 from KayenEQ/Development
Fix to check if weapon actually has a valid proc before trying to proc.
2015-03-10 00:34:01 -04:00
KayenEQ 2cf2ef4fac Fix to check if weapon actually has a valid proc before trying to proc it. 2015-03-10 00:33:11 -04:00
KayenEQ c305582c77 Merge pull request #385 from KayenEQ/Development
perl $npc->GetCombatState
2015-03-09 06:40:55 -04:00
KayenEQ 69d02b7e72 perl $npc->GetCombatState 2015-03-09 06:40:13 -04:00
Uleat c96ee79b1e Added ';' to safe_delete_array(data) in ~BulkZoneSpawnPacket() 2015-03-06 04:26:26 -05:00
Alex bd9665e35b Merge pull request #381 from noudess/master
Allow server customization of swimming start value.
2015-03-04 19:37:01 -08:00
Akkadius 0210d6f6bf Fix Spell Book Deletion 2015-03-04 02:40:49 -06:00
Uleat fe294e60b5 Fix for 'Invalid Slot ID' messages, item loss during corpse looting, and possible item loss during LDoN/Adventure merchant purchases 2015-03-03 04:08:52 -05:00
Michael Cook (mackal) f95806b47b Move item caps that depend on spells/aas to be done after those are valid
Also fix Sleeper's Tomb avatar proc to be counted towards item ATK
2015-03-02 16:23:46 -05:00
KayenEQ 10f1e69ad8 Merge pull request #384 from KayenEQ/Development
fix to prior commit
2015-02-28 23:41:43 -05:00
KayenEQ d3249397f3 fix to prior commit 2015-02-28 23:39:44 -05:00
KayenEQ 69e9adf796 Merge pull request #383 from KayenEQ/Development
PERL remove proc functions
2015-02-28 23:25:23 -05:00
KayenEQ 4835b7063c PERL remove proc functions
$npc->RemoveMeleeProc(spell_id)
$npc->RemoveDefensiveProc(spell_id)
$npc->RemoveDefensiveProc(spell_id)
2015-02-28 23:24:19 -05:00
Uleat 8dfa0a7220 Final tweak for light sources 2015-02-27 19:28:28 -05:00
KayenEQ 2b8bdb9158 Merge pull request #382 from KayenEQ/Development
Fix for ModSkillDmgTaken to once again work with (-1 = ALL skills)
2015-02-27 03:12:36 -05:00
KayenEQ 7851f272e5 Fix for ModSkillDmgTaken to once again work with (-1 = ALL skills)
Fix for perl GetModSkillDmgTaken
2015-02-27 03:11:04 -05:00
Uleat e15ee6e320 Change for 'general' slot range light source behavior 2015-02-26 21:05:06 -05:00
Uleat 1f0b86a0d5 Changes to how valid light sources are critiqued 2015-02-26 18:46:12 -05:00
Michael Cook (mackal) e47f9d95b0 Fix title/suffix for RoF/RoF2 2015-02-24 16:26:25 -05:00
Uleat 0b6d71181f Added safety check to DraggedCorpses list iteration in Client::DraggedCorpses() 2015-02-24 00:52:18 -05:00
JJ 318a664b09 No "sigs". [skip ci] 2015-02-23 19:57:47 -05:00
Paul Coene 180c4c3286 Merge remote-tracking branch 'upstream/master'
Conflicts:
	changelog.txt
2015-02-23 19:11:35 -05:00
Paul Coene 221c1f17c7 Streamline changes for Swimming Rule and add Sense Heading rules 2015-02-23 19:03:28 -05:00
Uleat d601a70546 Fix for RoF+ clients showing active 'Return Home' button when action is not available 2015-02-23 18:42:12 -05:00
Paul Coene ba49e5f696 Allow servers to set starting value for swimming instead of the hard coded
value.
2015-02-23 13:32:10 -05:00
Paul Coene 19fc02c284 Merge remote-tracking branch 'upstream/master'
Conflicts:
	changelog.txt
	world/worlddb.cpp
2015-02-23 08:13:09 -05:00
KayenEQ b05581499a Merge pull request #380 from KayenEQ/Development
perl npc last name related functions.
2015-02-23 03:53:41 -05:00
KayenEQ 9d866c1889 perl $npc->ChangeLastName(name)
perl $npc->ClearLastName()
Modifies NPC last names.
2015-02-23 03:52:43 -05:00
KayenEQ a567812f35 Merge pull request #379 from KayenEQ/Development
perl NPC function RemoveFromHateList(mob)
2015-02-23 00:41:13 -05:00
KayenEQ 167b6f5ebf perl NPC function RemoveFromHateList(mob) 2015-02-23 00:39:06 -05:00
Uleat 2bed129037 Fix for tutorial button kicking client when re-entering tutorial (return home button for RoF/RoF2 issue still at large) 2015-02-22 22:27:58 -05:00
KayenEQ a0ea6066ed Merge pull request #378 from KayenEQ/Development
Fix for perl defensive/ranged proc function
2015-02-21 23:06:19 -05:00
KayenEQ c8c2209617 Fix for perl defensive/ranged proc function
Minor fix to NPC ranged attack.
2015-02-21 23:04:24 -05:00
JJ eff818ca42 Manual merge of #376 for Erudite starting zones. 2015-02-21 20:46:19 -05:00
KayenEQ a537981ad0 Merge pull request #377 from KayenEQ/Development
Fix to allow for mana drain spells to work if client is full mana.
2015-02-21 06:52:14 -05:00
KayenEQ 32cb219e64 Fix to allow for mana drain spells to work if client is full mana. 2015-02-21 06:32:41 -05:00
Michael Cook (mackal) 4f3360aa49 More VS compile fixes (curse you clang/gcc!) 2015-02-21 01:51:41 -05:00
Uleat e61f647bf2 Fix for non-compliant assignment of non-integral type array 2015-02-21 01:20:13 -05:00
Michael Cook (mackal) 7afb29cf02 Fix another memleak in Client::TryReward 2015-02-20 21:10:53 -05:00
Michael Cook (mackal) 0a351bf6e1 VS didn't like this (it was illegal though, stupid gcc/clang) 2015-02-20 20:51:21 -05:00
Michael Cook (mackal) 9a19d59cf7 Fix memory leak in Client::TryRewards 2015-02-20 18:47:46 -05:00
Michael Cook (mackal) c5a217842f Fix issues with claims and implement for RoF/RoF2 2015-02-20 16:29:56 -05:00
Uleat 921a292f5b Fix for new Titanium to UF client accounts not allowing character creation 2015-02-19 21:56:14 -05:00
Trevius 3b45a66498 Fix for potential recursive loops if using RemoveFromHateList() within EVENT_HATE_LIST.
Some work on Bazaar searching, but not functional yet.
2015-02-18 21:32:18 -06:00
Uleat 414db873b7 Fix for tints not showing up at character select (world server) 2015-02-18 19:18:53 -05:00
Michael Cook (mackal) 7deb4d5e78 Fix potion belt loading 2015-02-18 18:28:46 -05:00
Paul Coene fe77c6fb3f Updated change log and made changes to worlddb.cpp so paineel characters
start in paineel again on Titanium.
2015-02-18 16:26:48 -05:00
Alex aaa9595b59 Merge pull request #372 from noudess/master
A non magical weapon with an augment tagged as magic now hits as magic
2015-02-18 12:52:56 -08:00
KimLS 2d40adcf66 Partial revert/rewrite of b6dd604, should be possible to get things on a hate list that have zero hate again 2015-02-18 12:39:28 -08:00
KayenEQ 57ccddbb36 Merge pull request #375 from KayenEQ/Development
Fix for taunt.
2015-02-18 02:47:37 -05:00
KayenEQ b6dd604de2 Fix for taunt.
Added additional check to prevent recourse spells from recoursing themselves and crashing.
2015-02-18 02:46:13 -05:00
Uleat 911a515923 Fix for MySQL query failure 2015-02-18 00:22:05 -05:00
Uleat ea38fd2421 Merge pull request #374 from EQEmu/character_limit
Variable per-client character creation limits
2015-02-17 19:59:05 -05:00
Uleat e7fc6420f2 Added changelog entry for character limit 2015-02-17 19:35:50 -05:00
Uleat 766641cd15 Implemented per-client character creation limits 2015-02-17 13:58:27 -05:00
Uleat e4be4d6895 Pre-purposed clean-up 2015-02-17 13:58:26 -05:00
Uleat 53a1faa36f Constant name and eqdictionary entry addition prior to per-client version limit activation 2015-02-17 13:58:25 -05:00
Uleat 20249cec67 Pre-purposed prep-work 2015-02-17 13:58:25 -05:00
Uleat dedbb3f6c8 Implemented higher bandolier and potion belt counts 2015-02-17 13:58:24 -05:00
Uleat 5a3b10a11c Constant name re-alignments prior to extended bandolier/potion belt activation 2015-02-17 13:58:23 -05:00
Uleat f1a25da065 Pre-purposed clean-up 2015-02-17 13:58:19 -05:00
Paul Coene f9dbea531c Added note about augs to changelog 2015-02-16 17:14:29 -05:00
Michael Cook (mackal) b48a712887 Send bard effect stuff for RoF2
Server side we still use the old system
Servers will need to update their items, PEQ's DB appears fine

RoF2 wasn't show anything, so we have to send it for them
2015-02-16 15:40:44 -05:00
Trevius 28be3b87b7 (RoF2) Bazaar Trading (Buying/Selling) is now fully functional. Bazaar (/bazaar) search is not yet functional. 2015-02-16 11:56:23 -06:00
KimLS db3feafe48 Fix for returning to bound zone you're already in 2015-02-14 20:05:54 -08:00
KimLS 9a78bac0d0 Changed save items back to true to be like old encode, no point tempting fate on that not breaking anything 2015-02-14 18:46:03 -08:00
KimLS f95e211d9b Fixes to OP_ZonePlayerToBind code, esp for RoF clients. 2015-02-14 18:32:49 -08:00
Michael Cook (mackal) 75809fc3bb Fix RoF2 Strategy 2015-02-14 14:21:50 -05:00
Trevius 811e8809cc (RoF2) Bazaar is now partially functional. RoF2 clients can start/end trader mode and other clients can purchase from them. No other functionality yet. 2015-02-14 11:09:36 -06:00
Paul Coene eaf5cea908 Fixed a comment 2015-02-14 10:29:43 -05:00
Akkadius 7ac7914f33 Set door zone to 32 bytes for consistency in copy [skip ci] 2015-02-13 03:50:01 -06:00
Akkadius da425195f9 Missed .sql file [skip ci] 2015-02-12 22:32:36 -06:00
Akkadius a544c681c7 Implement zone based gravity, required SQL DB change
- To test `zone` table `gravity` values, change the value and use #zheader <zoneshortname> to test
2015-02-12 22:09:17 -06:00
Akkadius fd45e8d21d Merge branch 'master' of https://github.com/EQEmu/Server 2015-02-12 20:52:24 -06:00
Akkadius 1966324112 Changed NPCTypes Data to bulk load when the zone loads or Repops, this bulk loading is stored in the npc_types cache 2015-02-12 19:57:24 -06:00
Michael Cook (mackal) d1be53bef2 Fix RoF2 disc stuff 2015-02-12 14:02:14 -05:00
Akkadius 16002eb62e ClientTaskState::GetTaskActivityDoneCountFromTaskID invalid Index return (Crash fix) 2015-02-12 01:54:41 -06:00
KimLS 2774d8e761 AddToHateList will no longer assert on other = nullptr, it will now just do nothing. Since the function can be called from perl/lua it's inapprops to let them just crash the server with an abort() from assert. 2015-02-11 21:56:58 -08:00
Trevius e07704e36b (RoF+) Bandolier no longer displays a Treasure Chest Icon when no Bandoliers are set. 2015-02-11 19:02:52 -06:00
Uleat 9f400c8d14 SharedBank Plat and Item HotKey fixes for RoF 2015-02-11 17:10:45 -05:00
Michael Cook (mackal) 2c31b348c3 RoF2 shared bank plat 2015-02-11 16:26:55 -05:00
Michael Cook (mackal) cefff6506f Fix issue with corpse spawn packets
Historically PC corpses used 3; it doesn't appear true with Tit+

Test case target a corpse and /ttell it :P
2015-02-11 13:20:32 -05:00
Paul Coene 8cde649e39 A non magical weapon with an augment tagged as magical now registers
as a magig weapon when attacking a creature requiring magic
2015-02-09 17:04:44 -05:00
253 changed files with 15653 additions and 13243 deletions
-12
View File
@@ -31,7 +31,6 @@
#EQEMU_SANITIZE_LUA_LIBS
#EQEMU_BUILD_CLIENT_FILES
#EQEMU_MAP_DIR
#EQEMU_ENABLE_PROFILING
#We set a fairly new version (as of 2013) because I found finding perl was a bit... buggy on older ones
#Can change this if you really want but you should upgrade!
@@ -258,7 +257,6 @@ OPTION(EQEMU_BUILD_TESTS "Build utility tests." OFF)
OPTION(EQEMU_BUILD_PERL "Build Perl parser." ON)
OPTION(EQEMU_BUILD_LUA "Build Lua parser." ON)
OPTION(EQEMU_BUILD_CLIENT_FILES "Build Client Import/Export Data Programs." ON)
OPTION(EQEMU_ENABLE_PROFILING "Enable CPU profiler. Note: will slow down execution time." OFF)
#C++11 stuff
IF(NOT MSVC)
@@ -333,16 +331,6 @@ IF(EQEMU_BUILD_LUA)
ADD_SUBDIRECTORY(luabind)
ENDIF(EQEMU_BUILD_LUA)
IF(EQEMU_ENABLE_PROFILING)
ADD_DEFINITIONS(-DEQPERF_ENABLED)
ADD_DEFINITIONS(-DEQP_MULTITHREAD)
INCLUDE_DIRECTORIES("eqperf")
ADD_SUBDIRECTORY(eqperf)
SET(PERF_LIBS eqperf)
ELSE(EQEMU_ENABLE_PROFILING)
SET(PERF_LIBS "")
ENDIF(EQEMU_ENABLE_PROFILING)
IF(EQEMU_BUILD_SERVER OR EQEMU_BUILD_LOGIN OR EQEMU_BUILD_TESTS)
ADD_SUBDIRECTORY(common)
ENDIF(EQEMU_BUILD_SERVER OR EQEMU_BUILD_LOGIN OR EQEMU_BUILD_TESTS)
+323 -207
View File
File diff suppressed because it is too large Load Diff
+1 -4
View File
@@ -11,17 +11,15 @@ ADD_EXECUTABLE(export_client_files ${export_sources} ${export_headers})
INSTALL(TARGETS export_client_files RUNTIME DESTINATION ${CMAKE_INSTALL_PREFIX})
TARGET_LINK_LIBRARIES(export_client_files common ${PERF_LIBS} debug ${MySQL_LIBRARY_DEBUG} optimized ${MySQL_LIBRARY_RELEASE} ${ZLIB_LIBRARY})
TARGET_LINK_LIBRARIES(export_client_files common debug ${MySQL_LIBRARY_DEBUG} optimized ${MySQL_LIBRARY_RELEASE} ${ZLIB_LIBRARY})
IF(MSVC)
SET_TARGET_PROPERTIES(export_client_files PROPERTIES LINK_FLAGS_RELEASE "/OPT:REF /OPT:ICF")
TARGET_LINK_LIBRARIES(export_client_files "Ws2_32.lib")
TARGET_LINK_LIBRARIES(export_client_files "rpcrt4")
ENDIF(MSVC)
IF(MINGW)
TARGET_LINK_LIBRARIES(export_client_files "WS2_32")
TARGET_LINK_LIBRARIES(export_client_files "rpcrt4")
ENDIF(MINGW)
IF(UNIX)
@@ -32,7 +30,6 @@ IF(UNIX)
TARGET_LINK_LIBRARIES(export_client_files "rt")
ENDIF(NOT DARWIN)
TARGET_LINK_LIBRARIES(export_client_files "pthread")
TARGET_LINK_LIBRARIES(export_client_files "uuid")
ADD_DEFINITIONS(-fPIC)
ENDIF(UNIX)
+34 -1
View File
@@ -32,6 +32,7 @@ EQEmuLogSys Log;
void ExportSpells(SharedDatabase *db);
void ExportSkillCaps(SharedDatabase *db);
void ExportBaseData(SharedDatabase *db);
void ExportDBStrings(SharedDatabase *db);
int main(int argc, char **argv) {
RegisterExecutablePlatform(ExePlatformClientExport);
@@ -62,6 +63,7 @@ int main(int argc, char **argv) {
ExportSpells(&database);
ExportSkillCaps(&database);
ExportBaseData(&database);
ExportDBStrings(&database);
Log.CloseFileLogs();
@@ -194,7 +196,38 @@ void ExportBaseData(SharedDatabase *db) {
fprintf(f, "%s\n", line.c_str());
}
} else {
}
fclose(f);
}
void ExportDBStrings(SharedDatabase *db) {
Log.Out(Logs::General, Logs::Status, "Exporting DB Strings...");
FILE *f = fopen("export/dbstr_us.txt", "w");
if(!f) {
Log.Out(Logs::General, Logs::Error, "Unable to open export/dbstr_us.txt to write, skipping.");
return;
}
fprintf(f, "Major^Minor^String(New)\n");
const std::string query = "SELECT * FROM db_str ORDER BY id, type";
auto results = db->QueryDatabase(query);
if(results.Success()) {
for(auto row = results.begin(); row != results.end(); ++row) {
std::string line;
unsigned int fields = results.ColumnCount();
for(unsigned int rowIndex = 0; rowIndex < fields; ++rowIndex) {
if(rowIndex != 0)
line.push_back('^');
if(row[rowIndex] != nullptr) {
line += row[rowIndex];
}
}
fprintf(f, "%s\n", line.c_str());
}
}
fclose(f);
+1 -4
View File
@@ -11,17 +11,15 @@ ADD_EXECUTABLE(import_client_files ${import_sources} ${import_headers})
INSTALL(TARGETS import_client_files RUNTIME DESTINATION ${CMAKE_INSTALL_PREFIX})
TARGET_LINK_LIBRARIES(import_client_files common ${PERF_LIBS} debug ${MySQL_LIBRARY_DEBUG} optimized ${MySQL_LIBRARY_RELEASE} ${ZLIB_LIBRARY})
TARGET_LINK_LIBRARIES(import_client_files common debug ${MySQL_LIBRARY_DEBUG} optimized ${MySQL_LIBRARY_RELEASE} ${ZLIB_LIBRARY})
IF(MSVC)
SET_TARGET_PROPERTIES(import_client_files PROPERTIES LINK_FLAGS_RELEASE "/OPT:REF /OPT:ICF")
TARGET_LINK_LIBRARIES(import_client_files "Ws2_32.lib")
TARGET_LINK_LIBRARIES(import_client_files "rpcrt4")
ENDIF(MSVC)
IF(MINGW)
TARGET_LINK_LIBRARIES(import_client_files "WS2_32")
TARGET_LINK_LIBRARIES(import_client_files "rpcrt4")
ENDIF(MINGW)
IF(UNIX)
@@ -32,7 +30,6 @@ IF(UNIX)
TARGET_LINK_LIBRARIES(import_client_files "rt")
ENDIF(NOT DARWIN)
TARGET_LINK_LIBRARIES(import_client_files "pthread")
TARGET_LINK_LIBRARIES(import_client_files "uuid")
ADD_DEFINITIONS(-fPIC)
ENDIF(UNIX)
+55 -1
View File
@@ -30,6 +30,7 @@ EQEmuLogSys Log;
void ImportSpells(SharedDatabase *db);
void ImportSkillCaps(SharedDatabase *db);
void ImportBaseData(SharedDatabase *db);
void ImportDBStrings(SharedDatabase *db);
int main(int argc, char **argv) {
RegisterExecutablePlatform(ExePlatformClientImport);
@@ -59,6 +60,7 @@ int main(int argc, char **argv) {
ImportSpells(&database);
ImportSkillCaps(&database);
ImportBaseData(&database);
ImportDBStrings(&database);
Log.CloseFileLogs();
@@ -202,7 +204,6 @@ void ImportSkillCaps(SharedDatabase *db) {
continue;
}
int class_id, skill_id, level, cap;
class_id = atoi(split[0].c_str());
skill_id = atoi(split[1].c_str());
@@ -262,3 +263,56 @@ void ImportBaseData(SharedDatabase *db) {
fclose(f);
}
void ImportDBStrings(SharedDatabase *db) {
Log.Out(Logs::General, Logs::Status, "Importing DB Strings...");
FILE *f = fopen("import/dbstr_us.txt", "r");
if(!f) {
Log.Out(Logs::General, Logs::Error, "Unable to open import/dbstr_us.txt to read, skipping.");
return;
}
std::string delete_sql = "DELETE FROM db_str";
db->QueryDatabase(delete_sql);
char buffer[2048];
bool first = true;
while(fgets(buffer, 2048, f)) {
if(first) {
first = false;
continue;
}
for(int i = 0; i < 2048; ++i) {
if(buffer[i] == '\n') {
buffer[i] = 0;
break;
}
}
auto split = SplitString(buffer, '^');
if(split.size() < 2) {
continue;
}
std::string sql;
int id, type;
std::string value;
id = atoi(split[0].c_str());
type = atoi(split[1].c_str());
if(split.size() >= 3) {
value = ::EscapeString(split[2]);
}
sql = StringFormat("INSERT INTO db_str(id, type, value) VALUES(%u, %u, '%s')",
id, type, value.c_str());
db->QueryDatabase(sql);
}
fclose(f);
}
+8 -2
View File
@@ -28,6 +28,8 @@ SET(common_sources
eqtime.cpp
extprofile.cpp
faction.cpp
file_verify.cpp
file_verify_manager.cpp
guild_base.cpp
guilds.cpp
ipc_mutex.cpp
@@ -39,6 +41,7 @@ SET(common_sources
mutex.cpp
mysql_request_result.cpp
mysql_request_row.cpp
opcode_map.cpp
opcodemgr.cpp
packet_dump.cpp
packet_dump_file.cpp
@@ -48,6 +51,7 @@ SET(common_sources
proc_launcher.cpp
ptimer.cpp
races.cpp
rdtsc.cpp
rulesys.cpp
serverinfo.cpp
shareddb.cpp
@@ -60,7 +64,6 @@ SET(common_sources
timeoutmgr.cpp
timer.cpp
unix.cpp
uuid.cpp
worldconn.cpp
xml_parser.cpp
platform.cpp
@@ -129,6 +132,8 @@ SET(common_headers
extprofile.h
faction.h
features.h
file_verify.h
file_verify_manager.h
fixed_memory_hash_set.h
fixed_memory_variable_hash_set.h
global_define.h
@@ -157,10 +162,12 @@ SET(common_headers
packet_functions.h
platform.h
proc_launcher.h
profiler.h
ptimer.h
queue.h
races.h
random.h
rdtsc.h
rulesys.h
ruletypes.h
seperator.h
@@ -179,7 +186,6 @@ SET(common_headers
types.h
unix.h
useperl.h
uuid.h
version.h
worldconn.h
xml_parser.h
+1
View File
@@ -63,6 +63,7 @@ public:
void WriteFloat(float value) { *(float *)(pBuffer + _wpos) = value; _wpos += sizeof(float); }
void WriteDouble(double value) { *(double *)(pBuffer + _wpos) = value; _wpos += sizeof(double); }
void WriteString(const char * str) { uint32 len = static_cast<uint32>(strlen(str)) + 1; memcpy(pBuffer + _wpos, str, len); _wpos += len; }
void WriteData(const void *ptr, size_t n) { memcpy(pBuffer + _wpos, ptr, n); _wpos += n; }
uint8 ReadUInt8() { uint8 value = *(uint8 *)(pBuffer + _rpos); _rpos += sizeof(uint8); return value; }
uint8 ReadUInt8(uint32 Offset) const { uint8 value = *(uint8 *)(pBuffer + Offset); return value; }
+90 -12
View File
@@ -1,3 +1,24 @@
/*
EQEMu: Everquest Server Emulator
Copyright (C) 2001-2015 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 CLIENTVERSIONS_H
#define CLIENTVERSIONS_H
@@ -34,6 +55,8 @@ enum class ClientVersion
MobMerc,
MobBot,
MobPet,
MaxClientVersions
};
#define CLIENT_VERSION_COUNT 12
@@ -46,32 +69,87 @@ static const char* ClientVersionName(ClientVersion version)
switch (version)
{
case ClientVersion::Unknown:
return "ClientVersion::Unknown";
return "Unknown";
case ClientVersion::Client62:
return "ClientVersion::Client62";
return "Client62";
case ClientVersion::Titanium:
return "ClientVersion::Titanium";
return "Titanium";
case ClientVersion::SoF:
return "ClientVersion::SoF";
return "SoF";
case ClientVersion::SoD:
return "ClientVersion::SoD";
return "SoD";
case ClientVersion::UF:
return "ClientVersion::UF";
return "UF";
case ClientVersion::RoF:
return "ClientVersion::RoF";
return "RoF";
case ClientVersion::RoF2:
return "ClientVersion::RoF2";
return "RoF2";
case ClientVersion::MobNPC:
return "ClientVersion::MobNPC";
return "MobNPC";
case ClientVersion::MobMerc:
return "ClientVersion::MobMerc";
return "MobMerc";
case ClientVersion::MobBot:
return "ClientVersion::MobBot";
return "MobBot";
case ClientVersion::MobPet:
return "ClientVersion::MobPet";
return "MobPet";
default:
return "<ERROR> Invalid ClientVersion";
};
}
static uint32 ClientBitFromVersion(ClientVersion clientVersion)
{
switch (clientVersion)
{
case ClientVersion::Unknown:
case ClientVersion::Client62:
return 0;
case ClientVersion::Titanium:
case ClientVersion::SoF:
case ClientVersion::SoD:
case ClientVersion::UF:
case ClientVersion::RoF:
case ClientVersion::RoF2:
case ClientVersion::MobNPC:
case ClientVersion::MobMerc:
case ClientVersion::MobBot:
case ClientVersion::MobPet:
return ((uint32)1 << (static_cast<unsigned int>(clientVersion) - 1));
default:
return 0;
}
}
static ClientVersion ClientVersionFromBit(uint32 clientVersionBit)
{
switch (clientVersionBit)
{
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;
case ((uint32)1 << (static_cast<unsigned int>(ClientVersion::MobNPC) - 1)):
return ClientVersion::MobNPC;
case ((uint32)1 << (static_cast<unsigned int>(ClientVersion::MobMerc) - 1)):
return ClientVersion::MobMerc;
case ((uint32)1 << (static_cast<unsigned int>(ClientVersion::MobBot) - 1)):
return ClientVersion::MobBot;
case ((uint32)1 << (static_cast<unsigned int>(ClientVersion::MobPet) - 1)):
return ClientVersion::MobPet;
default:
return ClientVersion::Unknown;
}
}
#endif /* CLIENTVERSIONS_H */
+20 -90
View File
@@ -57,13 +57,11 @@ Establish a connection to a mysql database with the supplied parameters
Database::Database(const char* host, const char* user, const char* passwd, const char* database, uint32 port)
{
_eqp
DBInitVars();
Connect(host, user, passwd, database, port);
}
bool Database::Connect(const char* host, const char* user, const char* passwd, const char* database, uint32 port) {
_eqp
uint32 errnum= 0;
char errbuf[MYSQL_ERRMSG_SIZE];
if (!Open(host, user, passwd, database, port, &errnum, errbuf)) {
@@ -77,7 +75,6 @@ bool Database::Connect(const char* host, const char* user, const char* passwd, c
}
void Database::DBInitVars() {
_eqp
varcache_array = 0;
varcache_max = 0;
varcache_lastupdate = 0;
@@ -89,7 +86,6 @@ void Database::DBInitVars() {
Database::~Database()
{
_eqp
unsigned int x;
if (varcache_array) {
for (x=0; x<varcache_max; x++) {
@@ -105,7 +101,7 @@ Database::~Database()
Zero will also be returned if there is a database error.
*/
uint32 Database::CheckLogin(const char* name, const char* password, int16* oStatus) {
_eqp
if(strlen(name) >= 50 || strlen(password) >= 50)
return(0);
@@ -141,7 +137,6 @@ uint32 Database::CheckLogin(const char* name, const char* password, int16* oStat
//Get Banned IP Address List - Only return false if the incoming connection's IP address is not present in the banned_ips table.
bool Database::CheckBannedIPs(const char* loginIP)
{
_eqp
std::string query = StringFormat("SELECT ip_address FROM Banned_IPs WHERE ip_address='%s'", loginIP);
auto results = QueryDatabase(query);
@@ -158,7 +153,6 @@ bool Database::CheckBannedIPs(const char* loginIP)
}
bool Database::AddBannedIP(char* bannedIP, const char* notes) {
_eqp
std::string query = StringFormat("INSERT into Banned_IPs SET ip_address='%s', notes='%s'", bannedIP, notes);
auto results = QueryDatabase(query);
if (!results.Success()) {
@@ -168,7 +162,6 @@ bool Database::AddBannedIP(char* bannedIP, const char* notes) {
}
bool Database::CheckGMIPs(const char* ip_address, uint32 account_id) {
_eqp
std::string query = StringFormat("SELECT * FROM `gm_ips` WHERE `ip_address` = '%s' AND `account_id` = %i", ip_address, account_id);
auto results = QueryDatabase(query);
@@ -182,20 +175,17 @@ bool Database::AddBannedIP(char* bannedIP, const char* notes) {
}
bool Database::AddGMIP(char* ip_address, char* name) {
_eqp
std::string query = StringFormat("INSERT into `gm_ips` SET `ip_address` = '%s', `name` = '%s'", ip_address, name);
auto results = QueryDatabase(query);
return results.Success();
}
void Database::LoginIP(uint32 AccountID, const char* LoginIP) {
_eqp
std::string query = StringFormat("INSERT INTO account_ip SET accid=%i, ip='%s' ON DUPLICATE KEY UPDATE count=count+1, lastused=now()", AccountID, LoginIP);
QueryDatabase(query);
}
int16 Database::CheckStatus(uint32 account_id) {
_eqp
std::string query = StringFormat("SELECT `status`, UNIX_TIMESTAMP(`suspendeduntil`) as `suspendeduntil`, UNIX_TIMESTAMP() as `current`"
" FROM `account` WHERE `id` = %i", account_id);
@@ -225,7 +215,6 @@ int16 Database::CheckStatus(uint32 account_id) {
}
uint32 Database::CreateAccount(const char* name, const char* password, int16 status, uint32 lsaccount_id) {
_eqp
std::string query;
if (password)
@@ -249,7 +238,6 @@ uint32 Database::CreateAccount(const char* name, const char* password, int16 sta
}
bool Database::DeleteAccount(const char* name) {
_eqp
std::string query = StringFormat("DELETE FROM account WHERE name='%s';",name);
Log.Out(Logs::General, Logs::World_Server, "Account Attempting to be deleted:'%s'", name);
@@ -262,7 +250,6 @@ bool Database::DeleteAccount(const char* name) {
}
bool Database::SetLocalPassword(uint32 accid, const char* password) {
_eqp
std::string query = StringFormat("UPDATE account SET password=MD5('%s') where id=%i;", EscapeString(password).c_str(), accid);
auto results = QueryDatabase(query);
@@ -275,7 +262,6 @@ bool Database::SetLocalPassword(uint32 accid, const char* password) {
}
bool Database::SetAccountStatus(const char* name, int16 status) {
_eqp
std::string query = StringFormat("UPDATE account SET status=%i WHERE name='%s';", status, name);
std::cout << "Account being GM Flagged:" << name << ", Level: " << (int16) status << std::endl;
@@ -296,7 +282,6 @@ bool Database::SetAccountStatus(const char* name, int16 status) {
/* This initially creates the character during character create */
bool Database::ReserveName(uint32 account_id, char* name) {
_eqp
std::string query = StringFormat("SELECT `account_id`, `name` FROM `character_data` WHERE `name` = '%s'", name);
auto results = QueryDatabase(query);
for (auto row = results.begin(); row != results.end(); ++row) {
@@ -317,7 +302,6 @@ bool Database::ReserveName(uint32 account_id, char* name) {
returns false on failure, true otherwise
*/
bool Database::DeleteCharacter(char *name) {
_eqp
uint32 charid = 0;
if(!name || !strlen(name)) {
Log.Out(Logs::General, Logs::World_Server, "DeleteCharacter: request to delete without a name (empty char slot)");
@@ -375,7 +359,6 @@ bool Database::DeleteCharacter(char *name) {
}
bool Database::SaveCharacterCreate(uint32 character_id, uint32 account_id, PlayerProfile_Struct* pp){
_eqp
std::string query = StringFormat(
"REPLACE INTO `character_data` ("
"id,"
@@ -695,7 +678,6 @@ bool Database::SaveCharacterCreate(uint32 character_id, uint32 account_id, Playe
/* This only for new Character creation storing */
bool Database::StoreCharacter(uint32 account_id, PlayerProfile_Struct* pp, Inventory* inv) {
_eqp
uint32 charid = 0;
char zone[50];
float x, y, z;
@@ -750,7 +732,6 @@ bool Database::StoreCharacter(uint32 account_id, PlayerProfile_Struct* pp, Inven
}
uint32 Database::GetCharacterID(const char *name) {
_eqp
std::string query = StringFormat("SELECT `id` FROM `character_data` WHERE `name` = '%s'", name);
auto results = QueryDatabase(query);
auto row = results.begin();
@@ -767,7 +748,6 @@ uint32 Database::GetCharacterID(const char *name) {
Zero will also be returned if there is a database error.
*/
uint32 Database::GetAccountIDByChar(const char* charname, uint32* oCharID) {
_eqp
std::string query = StringFormat("SELECT `account_id`, `id` FROM `character_data` WHERE name='%s'", EscapeString(charname).c_str());
auto results = QueryDatabase(query);
@@ -792,7 +772,6 @@ uint32 Database::GetAccountIDByChar(const char* charname, uint32* oCharID) {
// Retrieve account_id for a given char_id
uint32 Database::GetAccountIDByChar(uint32 char_id) {
_eqp
std::string query = StringFormat("SELECT `account_id` FROM `character_data` WHERE `id` = %i LIMIT 1", char_id);
auto results = QueryDatabase(query);
if (!results.Success()) {
@@ -807,7 +786,6 @@ uint32 Database::GetAccountIDByChar(uint32 char_id) {
}
uint32 Database::GetAccountIDByName(const char* accname, int16* status, uint32* lsid) {
_eqp
if (!isAlphaNumeric(accname))
return 0;
@@ -839,7 +817,6 @@ uint32 Database::GetAccountIDByName(const char* accname, int16* status, uint32*
}
void Database::GetAccountName(uint32 accountid, char* name, uint32* oLSAccountID) {
_eqp
std::string query = StringFormat("SELECT `name`, `lsaccount_id` FROM `account` WHERE `id` = '%i'", accountid);
auto results = QueryDatabase(query);
@@ -860,7 +837,6 @@ void Database::GetAccountName(uint32 accountid, char* name, uint32* oLSAccountID
}
void Database::GetCharName(uint32 char_id, char* name) {
_eqp
std::string query = StringFormat("SELECT `name` FROM `character_data` WHERE id='%i'", char_id);
auto results = QueryDatabase(query);
@@ -875,7 +851,6 @@ void Database::GetCharName(uint32 char_id, char* name) {
}
bool Database::LoadVariables() {
_eqp
char *query = nullptr;
auto results = QueryDatabase(query, LoadVariables_MQ(&query));
@@ -892,14 +867,12 @@ bool Database::LoadVariables() {
uint32 Database::LoadVariables_MQ(char** query)
{
_eqp
return MakeAnyLenString(query, "SELECT varname, value, unix_timestamp() FROM variables where unix_timestamp(ts) >= %d", varcache_lastupdate);
}
// always returns true? not sure about this.
bool Database::LoadVariables_result(MySQLRequestResult results)
{
_eqp
uint32 i = 0;
LockMutex lock(&Mvarcache);
@@ -962,7 +935,6 @@ bool Database::LoadVariables_result(MySQLRequestResult results)
// Gets variable from 'variables' table
bool Database::GetVariable(const char* varname, char* varvalue, uint16 varvalue_len) {
_eqp
varvalue[0] = '\0';
LockMutex lock(&Mvarcache);
@@ -984,7 +956,7 @@ bool Database::GetVariable(const char* varname, char* varvalue, uint16 varvalue_
}
bool Database::SetVariable(const char* varname_in, const char* varvalue_in) {
_eqp
char *varname,*varvalue;
varname=(char *)malloc(strlen(varname_in)*2+1);
@@ -1024,7 +996,6 @@ bool Database::SetVariable(const char* varname_in, const char* varvalue_in) {
uint32 Database::GetMiniLoginAccount(char* ip)
{
_eqp
std::string query = StringFormat("SELECT `id` FROM `account` WHERE `minilogin_ip` = '%s'", ip);
auto results = QueryDatabase(query);
@@ -1037,7 +1008,7 @@ uint32 Database::GetMiniLoginAccount(char* ip)
// Get zone starting points from DB
bool Database::GetSafePoints(const char* short_name, uint32 version, float* safe_x, float* safe_y, float* safe_z, int16* minstatus, uint8* minlevel, char *flag_needed) {
_eqp
std::string query = StringFormat("SELECT safe_x, safe_y, safe_z, min_status, min_level, flag_needed FROM zone "
" WHERE short_name='%s' AND (version=%i OR version=0) ORDER BY version DESC", short_name, version);
auto results = QueryDatabase(query);
@@ -1067,7 +1038,7 @@ bool Database::GetSafePoints(const char* short_name, uint32 version, float* safe
}
bool Database::GetZoneLongName(const char* short_name, char** long_name, char* file_name, float* safe_x, float* safe_y, float* safe_z, uint32* graveyard_id, uint32* maxclients) {
_eqp
std::string query = StringFormat("SELECT long_name, file_name, safe_x, safe_y, safe_z, graveyard_id, maxclients FROM zone WHERE short_name='%s' AND version=0", short_name);
auto results = QueryDatabase(query);
@@ -1105,7 +1076,7 @@ bool Database::GetZoneLongName(const char* short_name, char** long_name, char* f
}
uint32 Database::GetZoneGraveyardID(uint32 zone_id, uint32 version) {
_eqp
std::string query = StringFormat("SELECT graveyard_id FROM zone WHERE zoneidnumber='%u' AND (version=%i OR version=0) ORDER BY version DESC", zone_id, version);
auto results = QueryDatabase(query);
@@ -1120,7 +1091,7 @@ uint32 Database::GetZoneGraveyardID(uint32 zone_id, uint32 version) {
}
bool Database::GetZoneGraveyard(const uint32 graveyard_id, uint32* graveyard_zoneid, float* graveyard_x, float* graveyard_y, float* graveyard_z, float* graveyard_heading) {
_eqp
std::string query = StringFormat("SELECT zone_id, x, y, z, heading FROM graveyard WHERE id=%i", graveyard_id);
auto results = QueryDatabase(query);
@@ -1148,7 +1119,6 @@ bool Database::GetZoneGraveyard(const uint32 graveyard_id, uint32* graveyard_zon
}
bool Database::LoadZoneNames() {
_eqp
std::string query("SELECT zoneidnumber, short_name FROM zone");
auto results = QueryDatabase(query);
@@ -1169,7 +1139,7 @@ bool Database::LoadZoneNames() {
}
uint32 Database::GetZoneID(const char* zonename) {
_eqp
if (zonename == nullptr)
return 0;
@@ -1181,7 +1151,6 @@ uint32 Database::GetZoneID(const char* zonename) {
}
const char* Database::GetZoneName(uint32 zoneID, bool ErrorUnknown) {
_eqp
auto iter = zonename_array.find(zoneID);
if (iter != zonename_array.end())
@@ -1194,7 +1163,7 @@ const char* Database::GetZoneName(uint32 zoneID, bool ErrorUnknown) {
}
uint8 Database::GetPEQZone(uint32 zoneID, uint32 version){
_eqp
std::string query = StringFormat("SELECT peqzone from zone where zoneidnumber='%i' AND (version=%i OR version=0) ORDER BY version DESC", zoneID, version);
auto results = QueryDatabase(query);
@@ -1212,7 +1181,6 @@ uint8 Database::GetPEQZone(uint32 zoneID, uint32 version){
bool Database::CheckNameFilter(const char* name, bool surname)
{
_eqp
std::string str_name = name;
if(surname)
@@ -1289,7 +1257,7 @@ bool Database::CheckNameFilter(const char* name, bool surname)
}
bool Database::AddToNameFilter(const char* name) {
_eqp
std::string query = StringFormat("INSERT INTO name_filter (name) values ('%s')", name);
auto results = QueryDatabase(query);
@@ -1305,7 +1273,6 @@ bool Database::AddToNameFilter(const char* name) {
}
uint32 Database::GetAccountIDFromLSID(uint32 iLSID, char* oAccountName, int16* oStatus) {
_eqp
uint32 account_id = 0;
std::string query = StringFormat("SELECT id, name, status FROM account WHERE lsaccount_id=%i", iLSID);
auto results = QueryDatabase(query);
@@ -1330,7 +1297,7 @@ uint32 Database::GetAccountIDFromLSID(uint32 iLSID, char* oAccountName, int16* o
}
void Database::GetAccountFromID(uint32 id, char* oAccountName, int16* oStatus) {
_eqp
std::string query = StringFormat("SELECT name, status FROM account WHERE id=%i", id);
auto results = QueryDatabase(query);
@@ -1350,12 +1317,10 @@ void Database::GetAccountFromID(uint32 id, char* oAccountName, int16* oStatus) {
}
void Database::ClearMerchantTemp(){
_eqp
QueryDatabase("DELETE FROM merchantlist_temp");
}
bool Database::UpdateName(const char* oldname, const char* newname) {
_eqp
std::cout << "Renaming " << oldname << " to " << newname << "..." << std::endl;
std::string query = StringFormat("UPDATE `character_data` SET `name` = '%s' WHERE `name` = '%s';", newname, oldname);
auto results = QueryDatabase(query);
@@ -1371,7 +1336,6 @@ bool Database::UpdateName(const char* oldname, const char* newname) {
// If the name is used or an error occurs, it returns false, otherwise it returns true
bool Database::CheckUsedName(const char* name) {
_eqp
std::string query = StringFormat("SELECT `id` FROM `character_data` WHERE `name` = '%s'", name);
auto results = QueryDatabase(query);
if (!results.Success()) {
@@ -1385,7 +1349,6 @@ bool Database::CheckUsedName(const char* name) {
}
uint8 Database::GetServerType() {
_eqp
std::string query("SELECT `value` FROM `variables` WHERE `varname` = 'ServerType' LIMIT 1");
auto results = QueryDatabase(query);
if (!results.Success()) {
@@ -1400,7 +1363,6 @@ uint8 Database::GetServerType() {
}
bool Database::MoveCharacterToZone(const char* charname, const char* zonename, uint32 zoneid) {
_eqp
if(zonename == nullptr || strlen(zonename) == 0)
return false;
@@ -1418,12 +1380,10 @@ bool Database::MoveCharacterToZone(const char* charname, const char* zonename, u
}
bool Database::MoveCharacterToZone(const char* charname, const char* zonename) {
_eqp
return MoveCharacterToZone(charname, zonename, GetZoneID(zonename));
}
bool Database::MoveCharacterToZone(uint32 iCharID, const char* iZonename) {
_eqp
std::string query = StringFormat("UPDATE `character_data` SET `zone_id` = %i, `x` = -1, `y` = -1, `z` = -1 WHERE `id` = %i", iZonename, GetZoneID(iZonename), iCharID);
auto results = QueryDatabase(query);
@@ -1435,7 +1395,6 @@ bool Database::MoveCharacterToZone(uint32 iCharID, const char* iZonename) {
}
bool Database::SetHackerFlag(const char* accountname, const char* charactername, const char* hacked) {
_eqp
std::string query = StringFormat("INSERT INTO `hackers` (account, name, hacked) values('%s','%s','%s')", accountname, charactername, hacked);
auto results = QueryDatabase(query);
@@ -1447,7 +1406,6 @@ bool Database::SetHackerFlag(const char* accountname, const char* charactername,
}
bool Database::SetMQDetectionFlag(const char* accountname, const char* charactername, const char* hacked, const char* zone) {
_eqp
//Utilize the "hacker" table, but also give zone information.
std::string query = StringFormat("INSERT INTO hackers(account,name,hacked,zone) values('%s','%s','%s','%s')", accountname, charactername, hacked, zone);
auto results = QueryDatabase(query);
@@ -1462,7 +1420,6 @@ bool Database::SetMQDetectionFlag(const char* accountname, const char* character
uint8 Database::GetRaceSkill(uint8 skillid, uint8 in_race)
{
_eqp
uint16 race_cap = 0;
//Check for a racial cap!
@@ -1481,7 +1438,6 @@ uint8 Database::GetRaceSkill(uint8 skillid, uint8 in_race)
uint8 Database::GetSkillCap(uint8 skillid, uint8 in_race, uint8 in_class, uint16 in_level)
{
_eqp
uint8 skill_level = 0, skill_formula = 0;
uint16 base_cap = 0, skill_cap = 0, skill_cap2 = 0, skill_cap3 = 0;
@@ -1531,7 +1487,6 @@ uint8 Database::GetSkillCap(uint8 skillid, uint8 in_race, uint8 in_class, uint16
}
uint32 Database::GetCharacterInfo(const char* iName, uint32* oAccID, uint32* oZoneID, uint32* oInstanceID, float* oX, float* oY, float* oZ) {
_eqp
std::string query = StringFormat("SELECT `id`, `account_id`, `zone_id`, `zone_instance`, `x`, `y`, `z` FROM `character_data` WHERE `name` = '%s'", iName);
auto results = QueryDatabase(query);
@@ -1555,7 +1510,7 @@ uint32 Database::GetCharacterInfo(const char* iName, uint32* oAccID, uint32* oZo
}
bool Database::UpdateLiveChar(char* charname,uint32 lsaccount_id) {
_eqp
std::string query = StringFormat("UPDATE account SET charname='%s' WHERE id=%i;",charname, lsaccount_id);
auto results = QueryDatabase(query);
@@ -1567,7 +1522,7 @@ bool Database::UpdateLiveChar(char* charname,uint32 lsaccount_id) {
}
bool Database::GetLiveChar(uint32 account_id, char* cname) {
_eqp
std::string query = StringFormat("SELECT charname FROM account WHERE id=%i", account_id);
auto results = QueryDatabase(query);
@@ -1586,31 +1541,26 @@ bool Database::GetLiveChar(uint32 account_id, char* cname) {
}
void Database::SetLFP(uint32 CharID, bool LFP) {
_eqp
std::string query = StringFormat("UPDATE `character_data` SET `lfp` = %i WHERE `id` = %i",LFP, CharID);
QueryDatabase(query);
}
void Database::SetLoginFlags(uint32 CharID, bool LFP, bool LFG, uint8 firstlogon) {
_eqp
std::string query = StringFormat("update `character_data` SET `lfp` = %i, `lfg` = %i, `firstlogon` = %i WHERE `id` = %i",LFP, LFG, firstlogon, CharID);
QueryDatabase(query);
}
void Database::SetLFG(uint32 CharID, bool LFG) {
_eqp
std::string query = StringFormat("update `character_data` SET `lfg` = %i WHERE `id` = %i",LFG, CharID);
QueryDatabase(query);
}
void Database::SetFirstLogon(uint32 CharID, uint8 firstlogon) {
_eqp
std::string query = StringFormat( "UPDATE `character_data` SET `firstlogon` = %i WHERE `id` = %i",firstlogon, CharID);
QueryDatabase(query);
}
void Database::AddReport(std::string who, std::string against, std::string lines) {
_eqp
char *escape_str = new char[lines.size()*2+1];
DoEscapeString(escape_str, lines.c_str(), lines.size());
@@ -1620,7 +1570,6 @@ void Database::AddReport(std::string who, std::string against, std::string lines
}
void Database::SetGroupID(const char* name, uint32 id, uint32 charid, uint32 ismerc) {
_eqp
std::string query;
if (id == 0) {
// removing from group
@@ -1640,14 +1589,12 @@ void Database::SetGroupID(const char* name, uint32 id, uint32 charid, uint32 ism
void Database::ClearAllGroups(void)
{
_eqp
std::string query("DELETE FROM `group_id`");
QueryDatabase(query);
return;
}
void Database::ClearGroup(uint32 gid) {
_eqp
ClearGroupLeader(gid);
if(gid == 0)
@@ -1663,7 +1610,6 @@ void Database::ClearGroup(uint32 gid) {
}
uint32 Database::GetGroupID(const char* name){
_eqp
std::string query = StringFormat("SELECT groupid from group_id where name='%s'", name);
auto results = QueryDatabase(query);
@@ -1674,7 +1620,7 @@ uint32 Database::GetGroupID(const char* name){
if (results.RowCount() == 0)
{
// Commenting this out until logging levels can prevent this from going to console
//Log.Out(Logs::General, Logs::None, "Character not in a group: %s", name);
//Log.Out(Logs::General, Logs::None,, "Character not in a group: %s", name);
return 0;
}
@@ -1685,7 +1631,6 @@ uint32 Database::GetGroupID(const char* name){
/* Is this really getting used properly... A half implementation ? Akkadius */
char* Database::GetGroupLeaderForLogin(const char* name, char* leaderbuf) {
_eqp
strcpy(leaderbuf, "");
uint32 group_id = 0;
@@ -1710,7 +1655,6 @@ char* Database::GetGroupLeaderForLogin(const char* name, char* leaderbuf) {
}
void Database::SetGroupLeaderName(uint32 gid, const char* name) {
_eqp
std::string query = StringFormat("UPDATE group_leaders SET leadername = '%s' WHERE gid = %u", EscapeString(name).c_str(), gid);
auto result = QueryDatabase(query);
@@ -1729,7 +1673,6 @@ void Database::SetGroupLeaderName(uint32 gid, const char* name) {
char *Database::GetGroupLeadershipInfo(uint32 gid, char* leaderbuf, char* maintank, char* assist, char* puller, char *marknpc, char *mentoree, int *mentor_percent, GroupLeadershipAA_Struct* GLAA)
{
_eqp
std::string query = StringFormat("SELECT `leadername`, `maintank`, `assist`, `puller`, `marknpc`, `mentoree`, `mentor_percent`, `leadershipaa` FROM `group_leaders` WHERE `gid` = %lu",(unsigned long)gid);
auto results = QueryDatabase(query);
@@ -1789,7 +1732,6 @@ char *Database::GetGroupLeadershipInfo(uint32 gid, char* leaderbuf, char* mainta
// Clearing all group leaders
void Database::ClearAllGroupLeaders(void) {
_eqp
std::string query("DELETE from group_leaders");
auto results = QueryDatabase(query);
@@ -1800,7 +1742,7 @@ void Database::ClearAllGroupLeaders(void) {
}
void Database::ClearGroupLeader(uint32 gid) {
_eqp
if(gid == 0)
{
ClearAllGroupLeaders();
@@ -1815,7 +1757,7 @@ void Database::ClearGroupLeader(uint32 gid) {
}
uint8 Database::GetAgreementFlag(uint32 acctid) {
_eqp
std::string query = StringFormat("SELECT rulesflag FROM account WHERE id=%i",acctid);
auto results = QueryDatabase(query);
@@ -1831,13 +1773,11 @@ uint8 Database::GetAgreementFlag(uint32 acctid) {
}
void Database::SetAgreementFlag(uint32 acctid) {
_eqp
std::string query = StringFormat("UPDATE account SET rulesflag=1 where id=%i", acctid);
QueryDatabase(query);
}
void Database::ClearRaid(uint32 rid) {
_eqp
if(rid == 0)
{
//clear all raids
@@ -1854,7 +1794,7 @@ void Database::ClearRaid(uint32 rid) {
}
void Database::ClearAllRaids(void) {
_eqp
std::string query("delete from raid_members");
auto results = QueryDatabase(query);
@@ -1864,7 +1804,7 @@ void Database::ClearAllRaids(void) {
void Database::ClearAllRaidDetails(void)
{
_eqp
std::string query("delete from raid_details");
auto results = QueryDatabase(query);
@@ -1873,7 +1813,7 @@ void Database::ClearAllRaidDetails(void)
}
void Database::ClearRaidDetails(uint32 rid) {
_eqp
if(rid == 0)
{
//clear all raids
@@ -1892,8 +1832,7 @@ void Database::ClearRaidDetails(uint32 rid) {
// returns 0 on error or no raid for that character, or
// the raid id that the character is a member of.
uint32 Database::GetRaidID(const char* name)
{
_eqp
{
std::string query = StringFormat("SELECT `raidid` FROM `raid_members` WHERE `name` = '%s'", name);
auto results = QueryDatabase(query);
@@ -1914,7 +1853,6 @@ uint32 Database::GetRaidID(const char* name)
const char* Database::GetRaidLeaderName(uint32 raid_id)
{
_eqp
// Would be a good idea to fix this to be a passed in variable and
// make the caller responsible. static local variables like this are
// not guaranteed to be thread safe (nor is the internal guard
@@ -1946,7 +1884,6 @@ const char* Database::GetRaidLeaderName(uint32 raid_id)
void Database::GetGroupLeadershipInfo(uint32 gid, uint32 rid, char *maintank,
char *assist, char *puller, char *marknpc, char *mentoree, int *mentor_percent, GroupLeadershipAA_Struct *GLAA)
{
_eqp
std::string query = StringFormat(
"SELECT maintank, assist, puller, marknpc, mentoree, mentor_percent, leadershipaa FROM raid_leaders WHERE gid = %lu AND rid = %lu",
(unsigned long)gid, (unsigned long)rid);
@@ -2004,7 +1941,6 @@ void Database::GetGroupLeadershipInfo(uint32 gid, uint32 rid, char *maintank,
void Database::GetRaidLeadershipInfo(uint32 rid, char *maintank,
char *assist, char *puller, char *marknpc, RaidLeadershipAA_Struct *RLAA)
{
_eqp
std::string query = StringFormat(
"SELECT maintank, assist, puller, marknpc, leadershipaa FROM raid_leaders WHERE gid = %lu AND rid = %lu",
(unsigned long)0xFFFFFFFF, (unsigned long)rid);
@@ -2048,7 +1984,6 @@ void Database::GetRaidLeadershipInfo(uint32 rid, char *maintank,
void Database::SetRaidGroupLeaderInfo(uint32 gid, uint32 rid)
{
_eqp
std::string query = StringFormat("UPDATE raid_leaders SET leadershipaa = '' WHERE gid = %lu AND rid = %lu",
(unsigned long)gid, (unsigned long)rid);
auto results = QueryDatabase(query);
@@ -2066,7 +2001,6 @@ void Database::SetRaidGroupLeaderInfo(uint32 gid, uint32 rid)
// Clearing all raid leaders
void Database::ClearAllRaidLeaders(void)
{
_eqp
std::string query("DELETE from raid_leaders");
QueryDatabase(query);
return;
@@ -2074,7 +2008,6 @@ void Database::ClearAllRaidLeaders(void)
void Database::ClearRaidLeader(uint32 gid, uint32 rid)
{
_eqp
if (rid == 0) {
ClearAllRaidLeaders();
return;
@@ -2086,7 +2019,7 @@ void Database::ClearRaidLeader(uint32 gid, uint32 rid)
void Database::UpdateAdventureStatsEntry(uint32 char_id, uint8 theme, bool win)
{
_eqp
std::string field;
switch(theme)
@@ -2139,7 +2072,6 @@ void Database::UpdateAdventureStatsEntry(uint32 char_id, uint8 theme, bool win)
bool Database::GetAdventureStats(uint32 char_id, AdventureStats_Struct *as)
{
_eqp
std::string query = StringFormat(
"SELECT "
"`guk_wins`, "
@@ -2186,7 +2118,6 @@ bool Database::GetAdventureStats(uint32 char_id, AdventureStats_Struct *as)
uint32 Database::GetGuildIDByCharID(uint32 character_id)
{
_eqp
std::string query = StringFormat("SELECT guild_id FROM guild_members WHERE char_id='%i'", character_id);
auto results = QueryDatabase(query);
@@ -2202,7 +2133,6 @@ uint32 Database::GetGuildIDByCharID(uint32 character_id)
void Database::LoadLogSettings(EQEmuLogSys::LogSettings* log_settings)
{
_eqp
std::string query =
"SELECT "
"log_category_id, "
+29 -18
View File
@@ -157,18 +157,29 @@ namespace Convert {
/*84*/ uint32 Points;
/*88*/
} PVPStatsEntry_Struct;
static const size_t BANDOLIERS_SIZE = 4;
static const size_t BANDOLIER_ITEM_COUNT = 4;
struct BandolierItem_Struct {
uint32 item_id;
uint32 icon;
char item_name[64];
uint32 ID;
uint32 Icon;
char Name[64];
};
struct Bandolier_Struct {
char name[32];
Convert::BandolierItem_Struct items[EmuConstants::BANDOLIER_SIZE];
char Name[32];
Convert::BandolierItem_Struct Items[Convert::BANDOLIER_ITEM_COUNT];
};
static const size_t POTION_BELT_ITEM_COUNT = 4;
struct PotionBeltItem_Struct {
uint32 ID;
uint32 Icon;
char Name[64];
};
struct PotionBelt_Struct {
Convert::BandolierItem_Struct items[EmuConstants::POTION_BELT_SIZE];
Convert::PotionBeltItem_Struct Items[Convert::POTION_BELT_ITEM_COUNT];
};
struct SuspendedMinion_Struct
{
/*000*/ uint16 SpellID;
@@ -346,7 +357,7 @@ namespace Convert {
/*12800*/ uint32 expAA;
/*12804*/ uint32 aapoints; //avaliable, unspent
/*12808*/ uint8 unknown12844[36];
/*12844*/ Convert::Bandolier_Struct bandoliers[EmuConstants::BANDOLIERS_COUNT];
/*12844*/ Convert::Bandolier_Struct bandoliers[Convert::BANDOLIERS_SIZE];
/*14124*/ uint8 unknown14160[4506];
/*18630*/ Convert::SuspendedMinion_Struct SuspendedMinion; // No longer in use
/*19240*/ uint32 timeentitledonaccount;
@@ -483,7 +494,7 @@ bool Database::CheckDatabaseConversions() {
/* 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 2");
system("perl eqemu_update.pl V 7");
/* Run Automatic Database Upgrade Script */
system("perl eqemu_update.pl ran_from_world");
@@ -1430,15 +1441,15 @@ bool Database::CheckDatabaseConvertPPDeblob(){
if (rquery != ""){ results = QueryDatabase(rquery); }
/* Run Bandolier Convert */
first_entry = 0; rquery = "";
for (i = 0; i < EmuConstants::BANDOLIERS_COUNT; i++){
if (strlen(pp->bandoliers[i].name) < 32) {
for (int si = 0; si < EmuConstants::BANDOLIER_SIZE; si++){
if (pp->bandoliers[i].items[si].item_id > 0){
for (i = 0; i < Convert::BANDOLIERS_SIZE; i++){
if (strlen(pp->bandoliers[i].Name) < 32) {
for (int si = 0; si < Convert::BANDOLIER_ITEM_COUNT; si++){
if (pp->bandoliers[i].Items[si].ID > 0){
if (first_entry != 1) {
rquery = StringFormat("REPLACE INTO `character_bandolier` (id, bandolier_id, bandolier_slot, item_id, icon, bandolier_name) VALUES (%i, %u, %i, %u, %u, '%s')", character_id, i, si, pp->bandoliers[i].items[si].item_id, pp->bandoliers[i].items[si].icon, pp->bandoliers[i].name);
rquery = StringFormat("REPLACE INTO `character_bandolier` (id, bandolier_id, bandolier_slot, item_id, icon, bandolier_name) VALUES (%i, %u, %i, %u, %u, '%s')", character_id, i, si, pp->bandoliers[i].Items[si].ID, pp->bandoliers[i].Items[si].Icon, pp->bandoliers[i].Name);
first_entry = 1;
}
rquery = rquery + StringFormat(", (%i, %u, %i, %u, %u, '%s')", character_id, i, si, pp->bandoliers[i].items[si].item_id, pp->bandoliers[i].items[si].icon, pp->bandoliers[i].name);
rquery = rquery + StringFormat(", (%i, %u, %i, %u, %u, '%s')", character_id, i, si, pp->bandoliers[i].Items[si].ID, pp->bandoliers[i].Items[si].Icon, pp->bandoliers[i].Name);
}
}
}
@@ -1446,13 +1457,13 @@ bool Database::CheckDatabaseConvertPPDeblob(){
if (rquery != ""){ results = QueryDatabase(rquery); }
/* Run Potion Belt Convert */
first_entry = 0; rquery = "";
for (i = 0; i < EmuConstants::POTION_BELT_SIZE; i++){
if (pp->potionbelt.items[i].item_id > 0){
for (i = 0; i < Convert::POTION_BELT_ITEM_COUNT; i++){
if (pp->potionbelt.Items[i].ID > 0){
if (first_entry != 1){
rquery = StringFormat("REPLACE INTO `character_potionbelt` (id, potion_id, item_id, icon) VALUES (%i, %u, %u, %u)", character_id, i, pp->potionbelt.items[i].item_id, pp->potionbelt.items[i].icon);
rquery = StringFormat("REPLACE INTO `character_potionbelt` (id, potion_id, item_id, icon) VALUES (%i, %u, %u, %u)", character_id, i, pp->potionbelt.Items[i].ID, pp->potionbelt.Items[i].Icon);
first_entry = 1;
}
rquery = rquery + StringFormat(", (%i, %u, %u, %u)", character_id, i, pp->potionbelt.items[i].item_id, pp->potionbelt.items[i].icon);
rquery = rquery + StringFormat(", (%i, %u, %u, %u)", character_id, i, pp->potionbelt.Items[i].ID, pp->potionbelt.Items[i].Icon);
}
}
+7 -6
View File
@@ -292,8 +292,6 @@ N(OP_LockoutTimerInfo),
N(OP_Login),
N(OP_LoginAccepted),
N(OP_LoginComplete),
N(OP_LoginUnknown1),
N(OP_LoginUnknown2),
N(OP_Logout),
N(OP_LogoutReply),
N(OP_LogServer),
@@ -348,6 +346,7 @@ N(OP_OpenTributeMaster),
N(OP_PDeletePetition),
N(OP_PetBuffWindow),
N(OP_PetCommands),
N(OP_PetHoTT),
N(OP_Petition),
N(OP_PetitionBug),
N(OP_PetitionCheckIn),
@@ -364,6 +363,8 @@ N(OP_PetitionUnCheckout),
N(OP_PetitionUpdate),
N(OP_PickPocket),
N(OP_PlayerProfile),
N(OP_PlayerStateAdd),
N(OP_PlayerStateRemove),
N(OP_PlayEverquestRequest),
N(OP_PlayEverquestResponse),
N(OP_PlayMP3),
@@ -519,15 +520,15 @@ N(OP_VetRewardsAvaliable),
N(OP_VoiceMacroIn),
N(OP_VoiceMacroOut),
N(OP_WeaponEquip1),
N(OP_WeaponEquip2),
N(OP_WeaponUnequip2),
N(OP_WearChange),
N(OP_Weather),
N(OP_Weblink),
N(OP_WhoAllRequest),
N(OP_WhoAllResponse),
N(OP_World_Client_CRC1),
N(OP_World_Client_CRC2),
N(OP_World_SpellFileCheck),
N(OP_World_SkillFileCheck),
N(OP_World_BaseDataFileCheck),
N(OP_World_ExeFileCheck),
N(OP_WorldClientReady),
N(OP_WorldComplete),
N(OP_WorldLogout),
-22
View File
@@ -50,7 +50,6 @@ EmuTCPConnection::EmuTCPConnection(uint32 ID, EmuTCPServer* iServer, SOCKET in_s
keepalive_timer(SERVER_TIMEOUT),
timeout_timer(SERVER_TIMEOUT * 2)
{
_eqp
id = 0;
Server = nullptr;
pOldFormat = iOldFormat;
@@ -77,7 +76,6 @@ EmuTCPConnection::EmuTCPConnection(bool iOldFormat, EmuTCPServer* iRelayServer,
keepalive_timer(SERVER_TIMEOUT),
timeout_timer(SERVER_TIMEOUT * 2)
{
_eqp
Server = iRelayServer;
if (Server)
RelayServer = true;
@@ -100,7 +98,6 @@ EmuTCPConnection::EmuTCPConnection(uint32 ID, EmuTCPServer* iServer, EmuTCPConne
keepalive_timer(SERVER_TIMEOUT),
timeout_timer(SERVER_TIMEOUT * 2)
{
_eqp
Server = iServer;
RelayLink = iRelayLink;
RelayServer = true;
@@ -120,7 +117,6 @@ EmuTCPConnection::~EmuTCPConnection() {
}
EmuTCPNetPacket_Struct* EmuTCPConnection::MakePacket(ServerPacket* pack, uint32 iDestination) {
_eqp
int32 size = sizeof(EmuTCPNetPacket_Struct) + pack->size;
if (pack->compressed) {
size += 4;
@@ -148,7 +144,6 @@ EmuTCPNetPacket_Struct* EmuTCPConnection::MakePacket(ServerPacket* pack, uint32
}
SPackSendQueue* EmuTCPConnection::MakeOldPacket(ServerPacket* pack) {
_eqp
SPackSendQueue* spsq = (SPackSendQueue*) new uchar[sizeof(SPackSendQueue) + pack->size + 4];
if (pack->pBuffer != 0 && pack->size != 0)
memcpy((char *) &spsq->buffer[4], (char *) pack->pBuffer, pack->size);
@@ -159,7 +154,6 @@ SPackSendQueue* EmuTCPConnection::MakeOldPacket(ServerPacket* pack) {
}
bool EmuTCPConnection::SendPacket(ServerPacket* pack, uint32 iDestination) {
_eqp
if (!Connected())
return false;
eTCPMode tmp = GetMode();
@@ -220,7 +214,6 @@ bool EmuTCPConnection::SendPacket(ServerPacket* pack, uint32 iDestination) {
}
bool EmuTCPConnection::SendPacket(EmuTCPNetPacket_Struct* tnps) {
_eqp
if (RemoteID)
return false;
if (!Connected())
@@ -261,7 +254,6 @@ bool EmuTCPConnection::SendPacket(EmuTCPNetPacket_Struct* tnps) {
}
ServerPacket* EmuTCPConnection::PopPacket() {
_eqp
ServerPacket* ret;
if (!MOutQueueLock.trylock())
return nullptr;
@@ -271,14 +263,12 @@ ServerPacket* EmuTCPConnection::PopPacket() {
}
void EmuTCPConnection::InModeQueuePush(EmuTCPNetPacket_Struct* tnps) {
_eqp
MSendQueue.lock();
InModeQueue.push(tnps);
MSendQueue.unlock();
}
void EmuTCPConnection::OutQueuePush(ServerPacket* pack) {
_eqp
MOutQueueLock.lock();
OutQueue.push(pack);
MOutQueueLock.unlock();
@@ -286,7 +276,6 @@ void EmuTCPConnection::OutQueuePush(ServerPacket* pack) {
bool EmuTCPConnection::LineOutQueuePush(char* line) {
_eqp
#if defined(GOTFRAGS) && 0
if (strcmp(line, "**CRASHME**") == 0) {
int i = 0;
@@ -380,7 +369,6 @@ bool EmuTCPConnection::LineOutQueuePush(char* line) {
}
void EmuTCPConnection::Disconnect(bool iSendRelayDisconnect) {
_eqp
TCPConnection::Disconnect();
if (RelayLink) {
@@ -390,7 +378,6 @@ void EmuTCPConnection::Disconnect(bool iSendRelayDisconnect) {
}
bool EmuTCPConnection::ConnectIP(uint32 irIP, uint16 irPort, char* errbuf) {
_eqp
if(!TCPConnection::ConnectIP(irIP, irPort, errbuf))
return(false);
@@ -445,7 +432,6 @@ bool EmuTCPConnection::ConnectIP(uint32 irIP, uint16 irPort, char* errbuf) {
}
void EmuTCPConnection::ClearBuffers() {
_eqp
TCPConnection::ClearBuffers();
LockMutex lock2(&MOutQueueLock);
@@ -462,7 +448,6 @@ void EmuTCPConnection::ClearBuffers() {
}
void EmuTCPConnection::SendNetErrorPacket(const char* reason) {
_eqp
#if TCPC_DEBUG >= 1
struct in_addr in;
in.s_addr = GetrIP();
@@ -484,7 +469,6 @@ void EmuTCPConnection::SendNetErrorPacket(const char* reason) {
}
void EmuTCPConnection::RemoveRelay(EmuTCPConnection* relay, bool iSendRelayDisconnect) {
_eqp
if (iSendRelayDisconnect) {
ServerPacket* pack = new ServerPacket(0, 5);
pack->pBuffer[0] = 3;
@@ -498,7 +482,6 @@ void EmuTCPConnection::RemoveRelay(EmuTCPConnection* relay, bool iSendRelayDisco
bool EmuTCPConnection::ProcessReceivedData(char* errbuf) {
_eqp
if (errbuf)
errbuf[0] = 0;
timeout_timer.Start();
@@ -522,7 +505,6 @@ bool EmuTCPConnection::ProcessReceivedData(char* errbuf) {
bool EmuTCPConnection::ProcessReceivedDataAsPackets(char* errbuf) {
_eqp
if (errbuf)
errbuf[0] = 0;
int32 base = 0;
@@ -639,7 +621,6 @@ bool EmuTCPConnection::ProcessReceivedDataAsPackets(char* errbuf) {
}
bool EmuTCPConnection::ProcessReceivedDataAsOldPackets(char* errbuf) {
_eqp
int32 base = 0;
int32 size = 4;
uchar* buffer;
@@ -714,7 +695,6 @@ bool EmuTCPConnection::ProcessReceivedDataAsOldPackets(char* errbuf) {
}
void EmuTCPConnection::ProcessNetworkLayerPacket(ServerPacket* pack) {
_eqp
uint8 opcode = pack->pBuffer[0];
uint8* data = &pack->pBuffer[1];
switch (opcode) {
@@ -800,7 +780,6 @@ void EmuTCPConnection::ProcessNetworkLayerPacket(ServerPacket* pack) {
}
bool EmuTCPConnection::SendData(bool &sent_something, char* errbuf) {
_eqp
sent_something = false;
if(!TCPConnection::SendData(sent_something, errbuf))
return(false);
@@ -820,7 +799,6 @@ bool EmuTCPConnection::SendData(bool &sent_something, char* errbuf) {
}
bool EmuTCPConnection::RecvData(char* errbuf) {
_eqp
if(!TCPConnection::RecvData(errbuf)) {
if (OutQueue.count())
return(true);
-8
View File
@@ -9,7 +9,6 @@ EmuTCPServer::EmuTCPServer(uint16 iPort, bool iOldFormat)
}
EmuTCPServer::~EmuTCPServer() {
_eqp
MInQueue.lock();
while(!m_InQueue.empty()) {
delete m_InQueue.front();
@@ -19,27 +18,23 @@ EmuTCPServer::~EmuTCPServer() {
}
void EmuTCPServer::Process() {
_eqp
CheckInQueue();
TCPServer<EmuTCPConnection>::Process();
}
void EmuTCPServer::CreateNewConnection(uint32 ID, SOCKET in_socket, uint32 irIP, uint16 irPort)
{
_eqp
EmuTCPConnection *conn = new EmuTCPConnection(ID, this, in_socket, irIP, irPort, pOldFormat);
AddConnection(conn);
}
void EmuTCPServer::SendPacket(ServerPacket* pack) {
_eqp
EmuTCPNetPacket_Struct* tnps = EmuTCPConnection::MakePacket(pack);
SendPacket(&tnps);
}
void EmuTCPServer::SendPacket(EmuTCPNetPacket_Struct** tnps) {
_eqp
MInQueue.lock();
m_InQueue.push(*tnps);
MInQueue.unlock();
@@ -47,7 +42,6 @@ void EmuTCPServer::SendPacket(EmuTCPNetPacket_Struct** tnps) {
}
void EmuTCPServer::CheckInQueue() {
_eqp
EmuTCPNetPacket_Struct* tnps = 0;
while (( tnps = InQueuePop() )) {
@@ -63,7 +57,6 @@ void EmuTCPServer::CheckInQueue() {
}
EmuTCPNetPacket_Struct* EmuTCPServer::InQueuePop() {
_eqp
EmuTCPNetPacket_Struct* ret = nullptr;
MInQueue.lock();
if(!m_InQueue.empty()) {
@@ -76,7 +69,6 @@ EmuTCPNetPacket_Struct* EmuTCPServer::InQueuePop() {
EmuTCPConnection *EmuTCPServer::FindConnection(uint32 iID) {
_eqp
vitr cur, end;
cur = m_list.begin();
end = m_list.end();
+48 -1
View File
@@ -21,6 +21,53 @@
#include "skills.h"
#include "types.h"
/*
** Light Types
**
*/
enum LightTypes
{
lightTypeNone = 0,
lightTypeCandle,
lightTypeTorch,
lightTypeTinyGlowingSkull,
lightTypeSmallLantern,
lightTypeSteinOfMoggok,
lightTypeLargeLantern,
lightTypeFlamelessLantern,
lightTypeGlobeOfStars,
lightTypeLightGlobe,
lightTypeLightstone,
lightTypeGreaterLightstone,
lightTypeFireBeetleEye,
lightTypeColdlight,
lightTypeUnknown1,
lightTypeUnknown2
};
#define LIGHT_TYPES_COUNT 16
/*
** Light Levels
**
*/
enum LightLevels
{
lightLevelUnlit = 0,
lightLevelCandle,
lightLevelTorch,
lightLevelSmallMagic,
lightLevelRedLight,
lightLevelBlueLight,
lightLevelSmallLantern,
lightLevelMagicLantern,
lightLevelLargeLantern,
lightLevelLargeMagic,
lightLevelBrilliant
};
#define LIGHT_LEVELS_COUNT 11
/*
** Item attributes
**
@@ -55,7 +102,7 @@ enum ItemClassTypes
**
** (ref: database and eqstr_us.txt)
**
** (Looking at a recent database, it's possible that some of the item values may be off [10-27-2013] -U)
** (Looking at a recent database, it's possible that some of the item values may be off [10-27-2013])
*/
enum ItemUseTypes : uint8
{
+102 -115
View File
@@ -1,7 +1,7 @@
/*
EQEMu: Everquest Server Emulator
Copyright (C) 2001-2014 EQEMu Development Team (http://eqemulator.net)
Copyright (C) 2001-2015 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
@@ -25,8 +25,10 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
// class EmuConstants
//
uint16 EmuConstants::InventoryMapSize(int16 indexMap) {
switch (indexMap) {
uint16 EmuConstants::InventoryMapSize(int16 indexMap)
{
switch (indexMap)
{
case MapPossessions:
return MAP_POSSESSIONS_SIZE;
case MapBank:
@@ -83,7 +85,8 @@ uint16 EmuConstants::InventoryMapSize(int16 indexMap) {
}
/*
std::string EmuConstants::InventoryLocationName(Location_Struct location) {
std::string EmuConstants::InventoryLocationName(Location_Struct location)
{
// not ready for implementation...
std::string ret_str;
StringFormat(ret_str, "%s, %s, %s, %s", InventoryMapName(location.map), InventoryMainName(location.main), InventorySubName(location.sub), InventoryAugName(location.aug));
@@ -91,8 +94,10 @@ std::string EmuConstants::InventoryLocationName(Location_Struct location) {
}
*/
std::string EmuConstants::InventoryMapName(int16 indexMap) {
switch (indexMap) {
std::string EmuConstants::InventoryMapName(int16 indexMap)
{
switch (indexMap)
{
case INVALID_INDEX:
return "Invalid Map";
case MapPossessions:
@@ -100,7 +105,7 @@ std::string EmuConstants::InventoryMapName(int16 indexMap) {
case MapBank:
return "Bank";
case MapSharedBank:
return "Shared Bank";
return "SharedBank";
case MapTrade:
return "Trade";
case MapWorld:
@@ -110,9 +115,9 @@ std::string EmuConstants::InventoryMapName(int16 indexMap) {
case MapTribute:
return "Tribute";
case MapTrophyTribute:
return "Trophy Tribute";
return "TrophyTribute";
case MapGuildTribute:
return "Guild Tribute";
return "GuildTribute";
case MapMerchant:
return "Merchant";
case MapDeleted:
@@ -124,23 +129,23 @@ std::string EmuConstants::InventoryMapName(int16 indexMap) {
case MapInspect:
return "Inspect";
case MapRealEstate:
return "Real Estate";
return "RealEstate";
case MapViewMODPC:
return "View MOD PC";
return "ViewMODPC";
case MapViewMODBank:
return "View MOD Bank";
return "ViewMODBank";
case MapViewMODSharedBank:
return "View MOD Shared Bank";
return "ViewMODSharedBank";
case MapViewMODLimbo:
return "View MOD Limbo";
return "ViewMODLimbo";
case MapAltStorage:
return "Alt Storage";
return "AltStorage";
case MapArchived:
return "Archived";
case MapMail:
return "Mail";
case MapGuildTrophyTribute:
return "Guild Trophy Tribute";
return "GuildTrophyTribute";
case MapKrono:
return "Krono";
case MapOther:
@@ -150,20 +155,22 @@ std::string EmuConstants::InventoryMapName(int16 indexMap) {
}
}
std::string EmuConstants::InventoryMainName(int16 indexMain) {
switch (indexMain) {
std::string EmuConstants::InventoryMainName(int16 indexMain)
{
switch (indexMain)
{
case INVALID_INDEX:
return "Invalid Main";
case MainCharm:
return "Charm";
case MainEar1:
return "Ear 1";
return "Ear1";
case MainHead:
return "Head";
case MainFace:
return "Face";
case MainEar2:
return "Ear 2";
return "Ear2";
case MainNeck:
return "Neck";
case MainShoulders:
@@ -173,9 +180,9 @@ std::string EmuConstants::InventoryMainName(int16 indexMain) {
case MainBack:
return "Back";
case MainWrist1:
return "Wrist 1";
return "Wrist1";
case MainWrist2:
return "Wrist 2";
return "Wrist2";
case MainRange:
return "Range";
case MainHands:
@@ -185,9 +192,9 @@ std::string EmuConstants::InventoryMainName(int16 indexMain) {
case MainSecondary:
return "Secondary";
case MainFinger1:
return "Finger 1";
return "Finger1";
case MainFinger2:
return "Finger 2";
return "Finger2";
case MainChest:
return "Chest";
case MainLegs:
@@ -197,30 +204,30 @@ std::string EmuConstants::InventoryMainName(int16 indexMain) {
case MainWaist:
return "Waist";
case MainPowerSource:
return "Power Source";
return "PowerSource";
case MainAmmo:
return "Ammo";
case MainGeneral1:
return "General 1";
return "General1";
case MainGeneral2:
return "General 2";
return "General2";
case MainGeneral3:
return "General 3";
return "General3";
case MainGeneral4:
return "General 4";
return "General4";
case MainGeneral5:
return "General 5";
return "General5";
case MainGeneral6:
return "General 6";
return "General6";
case MainGeneral7:
return "General 7";
return "General7";
case MainGeneral8:
return "General 8";
return "General8";
/*
case MainGeneral9:
return "General 9";
return "General9";
case MainGeneral10:
return "General 10";
return "General10";
*/
case MainCursor:
return "Cursor";
@@ -229,7 +236,8 @@ std::string EmuConstants::InventoryMainName(int16 indexMain) {
}
}
std::string EmuConstants::InventorySubName(int16 indexSub) {
std::string EmuConstants::InventorySubName(int16 indexSub)
{
if (indexSub == INVALID_INDEX)
return "Invalid Sub";
@@ -237,12 +245,13 @@ std::string EmuConstants::InventorySubName(int16 indexSub) {
return "Unknown Sub";
std::string ret_str;
ret_str = StringFormat("Container %i", (indexSub + 1)); // zero-based index..but, count starts at one
ret_str = StringFormat("Container%i", (indexSub + 1)); // zero-based index..but, count starts at one
return ret_str;
}
std::string EmuConstants::InventoryAugName(int16 indexAug) {
std::string EmuConstants::InventoryAugName(int16 indexAug)
{
if (indexAug == INVALID_INDEX)
return "Invalid Aug";
@@ -250,7 +259,7 @@ std::string EmuConstants::InventoryAugName(int16 indexAug) {
return "Unknown Aug";
std::string ret_str;
ret_str = StringFormat("Augment %i", (indexAug + 1)); // zero-based index..but, count starts at one
ret_str = StringFormat("Augment%i", (indexAug + 1)); // zero-based index..but, count starts at one
return ret_str;
}
@@ -260,14 +269,16 @@ std::string EmuConstants::InventoryAugName(int16 indexAug) {
// class EQLimits
//
// client validation
bool EQLimits::IsValidPCClientVersion(ClientVersion clientVersion) {
bool EQLimits::IsValidPCClientVersion(ClientVersion clientVersion)
{
if (clientVersion > ClientVersion::Unknown && clientVersion <= LAST_PC_CLIENT)
return true;
return false;
}
ClientVersion EQLimits::ValidatePCClientVersion(ClientVersion clientVersion) {
ClientVersion EQLimits::ValidatePCClientVersion(ClientVersion clientVersion)
{
if (clientVersion > ClientVersion::Unknown && clientVersion <= LAST_PC_CLIENT)
return clientVersion;
@@ -275,14 +286,16 @@ ClientVersion EQLimits::ValidatePCClientVersion(ClientVersion clientVersion) {
}
// npc validation
bool EQLimits::IsValidNPCClientVersion(ClientVersion clientVersion) {
bool EQLimits::IsValidNPCClientVersion(ClientVersion clientVersion)
{
if (clientVersion > LAST_PC_CLIENT && clientVersion <= LAST_NPC_CLIENT)
return true;
return false;
}
ClientVersion EQLimits::ValidateNPCClientVersion(ClientVersion clientVersion) {
ClientVersion EQLimits::ValidateNPCClientVersion(ClientVersion clientVersion)
{
if (clientVersion > LAST_PC_CLIENT && clientVersion <= LAST_NPC_CLIENT)
return clientVersion;
@@ -290,22 +303,47 @@ ClientVersion EQLimits::ValidateNPCClientVersion(ClientVersion clientVersion) {
}
// mob validation
bool EQLimits::IsValidMobClientVersion(ClientVersion clientVersion) {
bool EQLimits::IsValidMobClientVersion(ClientVersion clientVersion)
{
if (clientVersion > ClientVersion::Unknown && clientVersion <= LAST_NPC_CLIENT)
return true;
return false;
}
ClientVersion EQLimits::ValidateMobClientVersion(ClientVersion clientVersion) {
ClientVersion EQLimits::ValidateMobClientVersion(ClientVersion clientVersion)
{
if (clientVersion > ClientVersion::Unknown && clientVersion <= LAST_NPC_CLIENT)
return clientVersion;
return ClientVersion::Unknown;
}
// database
size_t EQLimits::CharacterCreationLimit(ClientVersion clientVersion)
{
static const size_t local[CLIENT_VERSION_COUNT] = {
/*Unknown*/ NOT_USED,
/*Client62*/ NOT_USED,
/*Titanium*/ Titanium::consts::CHARACTER_CREATION_LIMIT,
/*SoF*/ SoF::consts::CHARACTER_CREATION_LIMIT,
/*SoD*/ SoD::consts::CHARACTER_CREATION_LIMIT,
/*UF*/ UF::consts::CHARACTER_CREATION_LIMIT,
/*RoF*/ RoF::consts::CHARACTER_CREATION_LIMIT,
/*RoF2*/ RoF2::consts::CHARACTER_CREATION_LIMIT,
/*MobNPC*/ NOT_USED,
/*MobMerc*/ NOT_USED,
/*MobBot*/ NOT_USED,
/*MobPet*/ NOT_USED
};
return local[static_cast<unsigned int>(ValidateMobClientVersion(clientVersion))];
}
// inventory
uint16 EQLimits::InventoryMapSize(int16 indexMap, ClientVersion clientVersion) {
uint16 EQLimits::InventoryMapSize(int16 indexMap, ClientVersion clientVersion)
{
// not all maps will have an instantiated container..some are references for queue generators (i.e., bazaar, mail, etc...)
// a zero '0' indicates a needed value..otherwise, change to '_NOTUSED' for a null value so indices requiring research can be identified
// ALL of these values need to be verified before pushing to live
@@ -704,7 +742,8 @@ uint16 EQLimits::InventoryMapSize(int16 indexMap, ClientVersion clientVersion) {
return NOT_USED;
}
uint64 EQLimits::PossessionsBitmask(ClientVersion clientVersion) {
uint64 EQLimits::PossessionsBitmask(ClientVersion clientVersion)
{
// these are for the new inventory system (RoF)..not the current (Ti) one...
// 0x0000000000200000 is SlotPowerSource (SoF+)
// 0x0000000080000000 is SlotGeneral9 (RoF+)
@@ -730,7 +769,8 @@ uint64 EQLimits::PossessionsBitmask(ClientVersion clientVersion) {
//return local[static_cast<unsigned int>(ValidateMobClientVersion(clientVersion))];
}
uint64 EQLimits::EquipmentBitmask(ClientVersion clientVersion) {
uint64 EQLimits::EquipmentBitmask(ClientVersion clientVersion)
{
static const uint64 local[CLIENT_VERSION_COUNT] = {
/*Unknown*/ NOT_USED,
/*62*/ 0x00000000005FFFFF,
@@ -751,7 +791,8 @@ uint64 EQLimits::EquipmentBitmask(ClientVersion clientVersion) {
//return local[static_cast<unsigned int>(ValidateMobClientVersion(clientVersion))];
}
uint64 EQLimits::GeneralBitmask(ClientVersion clientVersion) {
uint64 EQLimits::GeneralBitmask(ClientVersion clientVersion)
{
static const uint64 local[CLIENT_VERSION_COUNT] = {
/*Unknown*/ NOT_USED,
/*62*/ 0x000000007F800000,
@@ -772,7 +813,8 @@ uint64 EQLimits::GeneralBitmask(ClientVersion clientVersion) {
//return local[static_cast<unsigned int>(ValidateMobClientVersion(clientVersion))];
}
uint64 EQLimits::CursorBitmask(ClientVersion clientVersion) {
uint64 EQLimits::CursorBitmask(ClientVersion clientVersion)
{
static const uint64 local[CLIENT_VERSION_COUNT] = {
/*Unknown*/ NOT_USED,
/*62*/ 0x0000000200000000,
@@ -793,7 +835,8 @@ uint64 EQLimits::CursorBitmask(ClientVersion clientVersion) {
//return local[static_cast<unsigned int>(ValidateMobClientVersion(clientVersion))];
}
bool EQLimits::AllowsEmptyBagInBag(ClientVersion clientVersion) {
bool EQLimits::AllowsEmptyBagInBag(ClientVersion clientVersion)
{
static const bool local[CLIENT_VERSION_COUNT] = {
/*Unknown*/ false,
/*62*/ false,
@@ -814,7 +857,8 @@ bool EQLimits::AllowsEmptyBagInBag(ClientVersion clientVersion) {
//return local[static_cast<unsigned int>(ValidateMobClientVersion(clientVersion))];
}
bool EQLimits::AllowsClickCastFromBag(ClientVersion clientVersion) {
bool EQLimits::AllowsClickCastFromBag(ClientVersion clientVersion)
{
static const bool local[CLIENT_VERSION_COUNT] = {
/*Unknown*/ false,
/*62*/ false,
@@ -835,7 +879,8 @@ bool EQLimits::AllowsClickCastFromBag(ClientVersion clientVersion) {
}
// items
uint16 EQLimits::ItemCommonSize(ClientVersion clientVersion) {
uint16 EQLimits::ItemCommonSize(ClientVersion clientVersion)
{
static const uint16 local[CLIENT_VERSION_COUNT] = {
/*Unknown*/ NOT_USED,
/*62*/ EmuConstants::ITEM_COMMON_SIZE,
@@ -855,7 +900,8 @@ uint16 EQLimits::ItemCommonSize(ClientVersion clientVersion) {
return local[static_cast<unsigned int>(ValidateMobClientVersion(clientVersion))];
}
uint16 EQLimits::ItemContainerSize(ClientVersion clientVersion) {
uint16 EQLimits::ItemContainerSize(ClientVersion clientVersion)
{
static const uint16 local[CLIENT_VERSION_COUNT] = {
/*Unknown*/ NOT_USED,
/*62*/ EmuConstants::ITEM_CONTAINER_SIZE,
@@ -875,7 +921,8 @@ uint16 EQLimits::ItemContainerSize(ClientVersion clientVersion) {
return local[static_cast<unsigned int>(ValidateMobClientVersion(clientVersion))];
}
bool EQLimits::CoinHasWeight(ClientVersion clientVersion) {
bool EQLimits::CoinHasWeight(ClientVersion clientVersion)
{
static const bool local[CLIENT_VERSION_COUNT] = {
/*Unknown*/ true,
/*62*/ true,
@@ -894,63 +941,3 @@ bool EQLimits::CoinHasWeight(ClientVersion clientVersion) {
return local[static_cast<unsigned int>(ValidateMobClientVersion(clientVersion))];
}
uint32 EQLimits::BandoliersCount(ClientVersion clientVersion) {
static const uint32 local[CLIENT_VERSION_COUNT] = {
/*Unknown*/ NOT_USED,
/*62*/ EmuConstants::BANDOLIERS_COUNT,
/*Titanium*/ EmuConstants::BANDOLIERS_COUNT,
/*SoF*/ EmuConstants::BANDOLIERS_COUNT,
/*SoD*/ EmuConstants::BANDOLIERS_COUNT,
/*Underfoot*/ EmuConstants::BANDOLIERS_COUNT,
/*RoF*/ EmuConstants::BANDOLIERS_COUNT,
/*RoF2*/ EmuConstants::BANDOLIERS_COUNT,
/*NPC*/ NOT_USED,
/*Merc*/ NOT_USED,
/*Bot*/ NOT_USED,
/*Pet*/ NOT_USED
};
return local[static_cast<unsigned int>(ValidateMobClientVersion(clientVersion))];
}
uint32 EQLimits::BandolierSize(ClientVersion clientVersion) {
static const uint32 local[CLIENT_VERSION_COUNT] = {
/*Unknown*/ NOT_USED,
/*62*/ EmuConstants::BANDOLIER_SIZE,
/*Titanium*/ EmuConstants::BANDOLIER_SIZE,
/*SoF*/ EmuConstants::BANDOLIER_SIZE,
/*SoD*/ EmuConstants::BANDOLIER_SIZE,
/*Underfoot*/ EmuConstants::BANDOLIER_SIZE,
/*RoF*/ EmuConstants::BANDOLIER_SIZE,
/*RoF2*/ EmuConstants::BANDOLIER_SIZE,
/*NPC*/ NOT_USED,
/*Merc*/ NOT_USED,
/*Bot*/ NOT_USED,
/*Pet*/ NOT_USED
};
return local[static_cast<unsigned int>(ValidateMobClientVersion(clientVersion))];
}
uint32 EQLimits::PotionBeltSize(ClientVersion clientVersion) {
static const uint32 local[CLIENT_VERSION_COUNT] = {
/*Unknown*/ NOT_USED,
/*62*/ EmuConstants::POTION_BELT_SIZE,
/*Titanium*/ EmuConstants::POTION_BELT_SIZE,
/*SoF*/ EmuConstants::POTION_BELT_SIZE,
/*SoD*/ EmuConstants::POTION_BELT_SIZE,
/*Underfoot*/ EmuConstants::POTION_BELT_SIZE,
/*RoF*/ EmuConstants::POTION_BELT_SIZE,
/*RoF2*/ EmuConstants::POTION_BELT_SIZE,
/*NPC*/ NOT_USED,
/*Merc*/ NOT_USED,
/*Bot*/ NOT_USED,
/*Pet*/ NOT_USED
};
return local[static_cast<unsigned int>(ValidateMobClientVersion(clientVersion))];
}
+16 -20
View File
@@ -1,7 +1,7 @@
/*
EQEMu: Everquest Server Emulator
Copyright (C) 2001-2014 EQEMu Development Team (http://eqemulator.net)
Copyright (C) 2001-2015 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
@@ -42,12 +42,15 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//using namespace RoF2::maps; // server inventory maps enumeration (code and database sync'd to reference)
//using namespace RoF::slots; // server possessions slots enumeration (code and database sync'd to reference)
class EmuConstants {
class EmuConstants
{
// an immutable value is required to initialize arrays, etc... use this class as a repository for those
public:
// database
static const ClientVersion CHARACTER_CREATION_CLIENT = ClientVersion::RoF2; // adjust according to starting item placement and target client
static const size_t CHARACTER_CREATION_LIMIT = RoF2::consts::CHARACTER_CREATION_LIMIT;
// inventory
static uint16 InventoryMapSize(int16 indexMap);
//static std::string InventoryLocationName(Location_Struct location);
@@ -140,23 +143,18 @@ public:
static const uint16 ITEM_COMMON_SIZE = RoF::consts::ITEM_COMMON_SIZE;
static const uint16 ITEM_CONTAINER_SIZE = Titanium::consts::ITEM_CONTAINER_SIZE;
// player profile
//static const uint32 CLASS_BITMASK = 0; // needs value
//static const uint32 RACE_BITMASK = 0; // needs value
// BANDOLIERS_SIZE sets maximum limit..active limit will need to be handled by the appropriate AA or spell (or item?)
static const size_t BANDOLIERS_SIZE = RoF2::consts::BANDOLIERS_SIZE; // number of bandolier instances
static const size_t BANDOLIER_ITEM_COUNT = RoF2::consts::BANDOLIER_ITEM_COUNT; // number of equipment slots in bandolier instance
// BANDOLIERS_COUNT sets maximum limit..active limit will need to be handled by the appropriate AA
static const uint32 BANDOLIERS_COUNT = Titanium::consts::BANDOLIERS_COUNT; // count = number of bandolier instances
static const uint32 BANDOLIER_SIZE = Titanium::consts::BANDOLIER_SIZE; // size = number of equipment slots in bandolier instance
static const uint32 POTION_BELT_SIZE = Titanium::consts::POTION_BELT_SIZE;
// POTION_BELT_SIZE sets maximum limit..active limit will need to be handled by the appropriate AA or spell (or item?)
static const size_t POTION_BELT_ITEM_COUNT = RoF2::consts::POTION_BELT_ITEM_COUNT;
static const size_t TEXT_LINK_BODY_LENGTH = 56;
// legacy-related functions
//static int ServerToPerlSlot(int slot); // encode
//static int PerlToServerSlot(int slot); // decode
static const size_t TEXT_LINK_BODY_LENGTH = RoF2::consts::TEXT_LINK_BODY_LENGTH;
};
class EQLimits {
class EQLimits
{
// values should default to a non-beneficial value..unless value conflicts with intended operation
//
// EmuConstants may be used as references..but, not every reference needs to be in EmuConstants (i.e., AllowsEmptyBagInBag(), CoinHasWeight(), etc...)
@@ -174,6 +172,9 @@ public:
static bool IsValidMobClientVersion(ClientVersion clientVersion);
static ClientVersion ValidateMobClientVersion(ClientVersion clientVersion);
// database
static size_t CharacterCreationLimit(ClientVersion clientVersion);
// inventory
static uint16 InventoryMapSize(int16 indexMap, ClientVersion clientVersion);
static uint64 PossessionsBitmask(ClientVersion clientVersion);
@@ -190,11 +191,6 @@ public:
// player profile
static bool CoinHasWeight(ClientVersion clientVersion);
static uint32 BandoliersCount(ClientVersion clientVersion);
static uint32 BandolierSize(ClientVersion clientVersion);
static uint32 PotionBeltSize(ClientVersion clientVersion);
};
#endif /* EQ_DICTIONARY_H */
+77 -38
View File
@@ -40,11 +40,9 @@ EQPacket::EQPacket(EmuOpcode op, const unsigned char *buf, uint32 len)
: BasePacket(buf, len),
emu_opcode(op)
{
_eqp
}
void EQPacket::build_raw_header_dump(char *buffer, uint16 seq) const {
_eqp
BasePacket::build_raw_header_dump(buffer, seq);
buffer += strlen(buffer);
@@ -53,20 +51,17 @@ void EQPacket::build_raw_header_dump(char *buffer, uint16 seq) const {
void EQPacket::DumpRawHeader(uint16 seq, FILE *to) const
{
_eqp
char buff[196];
build_raw_header_dump(buff, seq);
fprintf(to, "%s", buff);
}
void EQPacket::build_header_dump(char *buffer) const {
_eqp
sprintf(buffer, "[EmuOpCode 0x%04x Size=%u]", emu_opcode, size);
}
void EQPacket::DumpRawHeaderNoTime(uint16 seq, FILE *to) const
{
_eqp
if (src_ip) {
std::string sIP,dIP;;
sIP=long2ip(src_ip);
@@ -81,7 +76,6 @@ void EQPacket::DumpRawHeaderNoTime(uint16 seq, FILE *to) const
void EQProtocolPacket::build_raw_header_dump(char *buffer, uint16 seq) const
{
_eqp
BasePacket::build_raw_header_dump(buffer, seq);
buffer += strlen(buffer);
@@ -90,7 +84,6 @@ void EQProtocolPacket::build_raw_header_dump(char *buffer, uint16 seq) const
void EQProtocolPacket::DumpRawHeader(uint16 seq, FILE *to) const
{
_eqp
char buff[196];
build_raw_header_dump(buff, seq);
fprintf(to, "%s", buff);
@@ -98,13 +91,11 @@ void EQProtocolPacket::DumpRawHeader(uint16 seq, FILE *to) const
void EQProtocolPacket::build_header_dump(char *buffer) const
{
_eqp
sprintf(buffer, "[ProtoOpCode 0x%04x Size=%u]",opcode,size);
}
void EQProtocolPacket::DumpRawHeaderNoTime(uint16 seq, FILE *to) const
{
_eqp
if (src_ip) {
std::string sIP,dIP;;
sIP=long2ip(src_ip);
@@ -119,7 +110,6 @@ void EQProtocolPacket::DumpRawHeaderNoTime(uint16 seq, FILE *to) const
void EQApplicationPacket::build_raw_header_dump(char *buffer, uint16 seq) const
{
_eqp
BasePacket::build_raw_header_dump(buffer, seq);
buffer += strlen(buffer);
@@ -132,7 +122,6 @@ void EQApplicationPacket::build_raw_header_dump(char *buffer, uint16 seq) const
void EQApplicationPacket::DumpRawHeader(uint16 seq, FILE *to) const
{
_eqp
char buff[196];
build_raw_header_dump(buff, seq);
fprintf(to, "%s", buff);
@@ -140,7 +129,6 @@ void EQApplicationPacket::DumpRawHeader(uint16 seq, FILE *to) const
void EQApplicationPacket::build_header_dump(char *buffer) const
{
_eqp
#ifdef STATIC_OPCODE
sprintf(buffer, "[OpCode 0x%04x Size=%u]\n", emu_opcode,size);
#else
@@ -150,7 +138,6 @@ void EQApplicationPacket::build_header_dump(char *buffer) const
void EQApplicationPacket::DumpRawHeaderNoTime(uint16 seq, FILE *to) const
{
_eqp
if (src_ip) {
std::string sIP,dIP;;
sIP=long2ip(src_ip);
@@ -169,7 +156,6 @@ void EQApplicationPacket::DumpRawHeaderNoTime(uint16 seq, FILE *to) const
void EQRawApplicationPacket::build_raw_header_dump(char *buffer, uint16 seq) const
{
_eqp
BasePacket::build_raw_header_dump(buffer, seq);
buffer += strlen(buffer);
@@ -182,7 +168,6 @@ void EQRawApplicationPacket::build_raw_header_dump(char *buffer, uint16 seq) con
void EQRawApplicationPacket::DumpRawHeader(uint16 seq, FILE *to) const
{
_eqp
char buff[196];
build_raw_header_dump(buff, seq);
fprintf(to, "%s", buff);
@@ -190,7 +175,6 @@ void EQRawApplicationPacket::DumpRawHeader(uint16 seq, FILE *to) const
void EQRawApplicationPacket::build_header_dump(char *buffer) const
{
_eqp
#ifdef STATIC_OPCODE
sprintf(buffer, "[OpCode 0x%04x (0x%04x) Size=%u]\n", emu_opcode, opcode,size);
#else
@@ -200,7 +184,6 @@ void EQRawApplicationPacket::build_header_dump(char *buffer) const
void EQRawApplicationPacket::DumpRawHeaderNoTime(uint16 seq, FILE *to) const
{
_eqp
if (src_ip) {
std::string sIP,dIP;;
sIP=long2ip(src_ip);
@@ -219,7 +202,6 @@ void EQRawApplicationPacket::DumpRawHeaderNoTime(uint16 seq, FILE *to) const
uint32 EQProtocolPacket::serialize(unsigned char *dest) const
{
_eqp
if (opcode>0xff) {
*(uint16 *)dest=opcode;
} else {
@@ -233,7 +215,6 @@ uint32 EQProtocolPacket::serialize(unsigned char *dest) const
uint32 EQApplicationPacket::serialize(uint16 opcode, unsigned char *dest) const
{
_eqp
uint8 OpCodeBytes = app_opcode_size;
if (app_opcode_size==1)
@@ -255,10 +236,29 @@ uint32 EQApplicationPacket::serialize(uint16 opcode, unsigned char *dest) const
return size+OpCodeBytes;
}
/*EQProtocolPacket::EQProtocolPacket(uint16 op, const unsigned char *buf, uint32 len)
: BasePacket(buf, len),
opcode(op)
{
uint32 offset;
opcode=ntohs(*(const uint16 *)buf);
offset=2;
if (len-offset) {
pBuffer= new unsigned char[len-offset];
memcpy(pBuffer,buf+offset,len-offset);
size=len-offset;
} else {
pBuffer=nullptr;
size=0;
}
OpMgr=&RawOpcodeManager;
}*/
bool EQProtocolPacket::combine(const EQProtocolPacket *rhs)
{
_eqp
bool result=false;
bool result=false;
if (opcode==OP_Combined && size+rhs->size+5<256) {
unsigned char *tmpbuffer=new unsigned char [size+rhs->size+3];
memcpy(tmpbuffer,pBuffer,size);
@@ -284,12 +284,61 @@ bool EQProtocolPacket::combine(const EQProtocolPacket *rhs)
}
return result;
}
/*
this is the code to do app-layer combining, instead of protocol layer.
this was taken out due to complex interactions with the opcode manager,
and will require a bit more thinking (likely moving into EQStream) to
get running again... but might be a good thing some day.
bool EQApplicationPacket::combine(const EQApplicationPacket *rhs)
{
uint32 newsize=0, offset=0;
unsigned char *tmpbuffer=nullptr;
if (opcode!=OP_AppCombined) {
newsize=app_opcode_size+size+(size>254?3:1)+app_opcode_size+rhs->size+(rhs->size>254?3:1);
tmpbuffer=new unsigned char [newsize];
offset=0;
if (size>254) {
tmpbuffer[offset++]=0xff;
*(uint16 *)(tmpbuffer+offset)=htons(size);
offset+=1;
} else {
tmpbuffer[offset++]=size;
}
offset+=serialize(tmpbuffer+offset);
} else {
newsize=size+app_opcode_size+rhs->size+(rhs->size>254?3:1);
tmpbuffer=new unsigned char [newsize];
memcpy(tmpbuffer,pBuffer,size);
offset=size;
}
if (rhs->size>254) {
tmpbuffer[offset++]=0xff;
*(uint16 *)(tmpbuffer+offset)=htons(rhs->size);
offset+=1;
} else {
tmpbuffer[offset++]=rhs->size;
}
offset+=rhs->serialize(tmpbuffer+offset);
size=offset;
opcode=OP_AppCombined;
delete[] pBuffer;
pBuffer=tmpbuffer;
return true;
}
*/
bool EQProtocolPacket::ValidateCRC(const unsigned char *buffer, int length, uint32 Key)
{
_eqp
bool valid=false;
bool valid=false;
// OP_SessionRequest, OP_SessionResponse, OP_OutOfSession are not CRC'd
if (buffer[0]==0x00 && (buffer[1]==OP_SessionRequest || buffer[1]==OP_SessionResponse || buffer[1]==OP_OutOfSession)) {
valid=true;
@@ -308,9 +357,8 @@ bool EQProtocolPacket::ValidateCRC(const unsigned char *buffer, int length, uint
uint32 EQProtocolPacket::Decompress(const unsigned char *buffer, const uint32 length, unsigned char *newbuf, uint32 newbufsize)
{
_eqp
uint32 newlen=0;
uint32 flag_offset=0;
uint32 newlen=0;
uint32 flag_offset=0;
newbuf[0]=buffer[0];
if (buffer[0]==0x00) {
flag_offset=2;
@@ -334,8 +382,7 @@ uint32 EQProtocolPacket::Decompress(const unsigned char *buffer, const uint32 le
}
uint32 EQProtocolPacket::Compress(const unsigned char *buffer, const uint32 length, unsigned char *newbuf, uint32 newbufsize) {
_eqp
uint32 flag_offset=1,newlength;
uint32 flag_offset=1,newlength;
//dump_message_column(buffer,length,"Before: ");
newbuf[0]=buffer[0];
if (buffer[0]==0) {
@@ -358,7 +405,6 @@ uint32 EQProtocolPacket::Compress(const unsigned char *buffer, const uint32 leng
void EQProtocolPacket::ChatDecode(unsigned char *buffer, int size, int DecodeKey)
{
_eqp
if ((size >= 2) && buffer[1]!=0x01 && buffer[0]!=0x02 && buffer[0]!=0x1d) {
int Key=DecodeKey;
unsigned char *test=(unsigned char *)malloc(size);
@@ -384,7 +430,6 @@ void EQProtocolPacket::ChatDecode(unsigned char *buffer, int size, int DecodeKey
void EQProtocolPacket::ChatEncode(unsigned char *buffer, int size, int EncodeKey)
{
_eqp
if (buffer[1]!=0x01 && buffer[0]!=0x02 && buffer[0]!=0x1d) {
int Key=EncodeKey;
char *test=(char*)malloc(size);
@@ -408,12 +453,10 @@ void EQProtocolPacket::ChatEncode(unsigned char *buffer, int size, int EncodeKey
}
EQApplicationPacket *EQApplicationPacket::Copy() const {
_eqp
return(new EQApplicationPacket(*this));
}
EQRawApplicationPacket *EQProtocolPacket::MakeAppPacket() const {
_eqp
EQRawApplicationPacket *res = new EQRawApplicationPacket(opcode, pBuffer, size);
res->copyInfo(this);
return(res);
@@ -423,13 +466,10 @@ EQRawApplicationPacket::EQRawApplicationPacket(uint16 opcode, const unsigned cha
: EQApplicationPacket(OP_Unknown, buf, len),
opcode(opcode)
{
_eqp
}
EQRawApplicationPacket::EQRawApplicationPacket(const unsigned char *buf, const uint32 len)
: EQApplicationPacket(OP_Unknown, buf+sizeof(uint16), len-sizeof(uint16))
{
_eqp
if(GetExecutablePlatform() != ExePlatformUCS) {
opcode = *((const uint16 *) buf);
if(opcode == 0x0000)
@@ -463,17 +503,16 @@ EQRawApplicationPacket::EQRawApplicationPacket(const unsigned char *buf, const u
}
void DumpPacket(const EQApplicationPacket* app, bool iShowInfo) {
_eqp
if (iShowInfo) {
std::cout << "Dumping Applayer: 0x" << std::hex << std::setfill('0') << std::setw(4) << app->GetOpcode() << std::dec;
std::cout << " size:" << app->size << std::endl;
}
DumpPacketHex(app->pBuffer, app->size);
// DumpPacketAscii(app->pBuffer, app->size);
}
std::string DumpPacketToString(const EQApplicationPacket* app){
_eqp
std::ostringstream out;
out << DumpPacketHexToString(app->pBuffer, app->size);
return out.str();
}
}
+184 -173
View File
@@ -15,6 +15,7 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef EQ_PACKET_STRUCTS_H
#define EQ_PACKET_STRUCTS_H
@@ -123,83 +124,81 @@ struct LDoNTrapTemplate
///////////////////////////////////////////////////////////////////////////////
/*
** Color_Struct
** Size: 4 bytes
** Used for convenience
** Merth: Gave struct a name so gcc 2.96 would compile
**
*/
// All clients translate the character select information to some degree
struct Color_Struct
{
union
{
struct
{
uint8 blue;
uint8 green;
uint8 red;
uint8 use_tint; // if there's a tint this is FF
} rgb;
uint32 color;
union {
struct {
uint8 Blue;
uint8 Green;
uint8 Red;
uint8 UseTint; // if there's a tint this is FF
} RGB;
uint32 Color;
};
};
/*
* 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 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
{
uint32 Material;
uint32 Unknown1;
uint32 EliteMaterial;
uint32 HeroForgeModel;
uint32 Material2;
Color_Struct Color;
};
/*
** Character Selection Struct
** Length: 1704 Bytes
**
*/
struct CharacterSelect_Struct {
/*0000*/ uint32 race[10]; // Characters Race
/*0040*/ //Color_Struct cs_colors[10][9]; // Characters Equipment Colors
/*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)
/*0000*/ CharSelectEquip equip[10][9];
/*0780*/ uint32 secondary[10]; // Characters secondary IDFile number
/*0820*/ uint32 drakkin_heritage[10]; // added for SoF
/*0860*/ uint32 drakkin_tattoo[10]; // added for SoF
/*0900*/ uint32 drakkin_details[10]; // added for SoF
/*0940*/ uint32 deity[10]; // Characters Deity
/*0980*/ uint8 gohome[10]; // 1=Go Home available, 0=not
/*0990*/ uint8 tutorial[10]; // 1=Tutorial available, 0=not
/*1000*/ uint8 beard[10]; // Characters Beard Type
/*1010*/ uint8 unknown902[10]; // 10x ff
/*1020*/ uint32 primary[10]; // Characters primary IDFile number
/*1060*/ uint8 haircolor[10]; // Characters Hair Color
/*1070*/ uint8 unknown0962[2]; // 2x 00
/*1072*/ uint32 zone[10]; // Characters Current Zone
/*1112*/ uint8 class_[10]; // Characters Classes
/*1022*/ uint8 face[10]; // Characters Face Type
/*1032*/ char name[10][64]; // Characters Names
/*1672*/ uint8 gender[10]; // Characters Gender
/*1682*/ uint8 eyecolor1[10]; // Characters Eye Color
/*1692*/ uint8 eyecolor2[10]; // Characters Eye 2 Color
/*1702*/ uint8 level[10]; // Characters Levels
/*1712*/
// RoF2-based hybrid struct
struct CharacterSelectEntry_Struct
{
char Name[64];
uint8 Class;
uint32 Race;
uint8 Level;
uint8 ShroudClass;
uint32 ShroudRace;
uint16 Zone;
uint16 Instance;
uint8 Gender;
uint8 Face;
CharSelectEquip Equip[9];
uint8 Unknown15; // Seen FF
uint8 Unknown19; // Seen FF
uint32 DrakkinTattoo;
uint32 DrakkinDetails;
uint32 Deity;
uint32 PrimaryIDFile;
uint32 SecondaryIDFile;
uint8 HairColor;
uint8 BeardColor;
uint8 EyeColor1;
uint8 EyeColor2;
uint8 HairStyle;
uint8 Beard;
uint8 GoHome; // Seen 0 for new char and 1 for existing
uint8 Tutorial; // Seen 1 for new char or 0 for existing
uint32 DrakkinHeritage;
uint8 Unknown1; // Seen 0
uint8 Enabled; // Originally labeled as 'CharEnabled' - unknown purpose and setting
uint32 LastLogin;
uint8 Unknown2; // Seen 0
};
struct CharacterSelect_Struct
{
uint32 CharCount; //number of chars in this packet
uint32 TotalChars; //total number of chars allowed?
CharacterSelectEntry_Struct Entries[0];
};
/*
@@ -274,7 +273,8 @@ struct Spawn_Struct {
/*0146*/ uint8 beard; // Beard style (not totally, sure but maybe!)
/*0147*/ uint8 unknown0147[4];
/*0151*/ uint8 level; // Spawn Level
/*0152*/ uint8 unknown0259[4]; // ***Placeholder
// None = 0, Open = 1, WeaponSheathed = 2, Aggressive = 4, ForcedAggressive = 8, InstrumentEquipped = 16, Stunned = 32, PrimaryWeaponEquipped = 64, SecondaryWeaponEquipped = 128
/*0152*/ uint32 PlayerState; // Controls animation stuff
/*0156*/ uint8 beardcolor; // Beard color
/*0157*/ char suffix[32]; // Player's suffix (of Veeshan, etc.)
/*0189*/ uint32 petOwnerId; // If this is a pet, the spawn id of owner
@@ -367,6 +367,11 @@ union
};
struct PlayerState_Struct {
/*00*/ uint32 spawn_id;
/*04*/ uint32 state;
};
/*
** New Spawn
** Length: 176 Bytes
@@ -548,7 +553,7 @@ struct SpellBuff_Struct
/*002*/ uint8 bard_modifier;
/*003*/ uint8 effect; //not real
/*004*/ uint32 spellid;
/*008*/ uint32 duration;
/*008*/ int32 duration;
/*012*/ uint32 counters;
/*016*/ uint32 player_id; //'global' ID of the caster, for wearoff messages
/*020*/
@@ -561,7 +566,7 @@ struct SpellBuffFade_Struct {
/*006*/ uint8 effect;
/*007*/ uint8 unknown7;
/*008*/ uint32 spellid;
/*012*/ uint32 duration;
/*012*/ int32 duration;
/*016*/ uint32 num_hits;
/*020*/ uint32 unknown020; //prolly global player ID
/*024*/ uint32 slotid;
@@ -579,14 +584,8 @@ struct BuffRemoveRequest_Struct
struct PetBuff_Struct {
/*000*/ uint32 petid;
/*004*/ uint32 spellid[BUFF_COUNT];
/*104*/ uint32 unknown700;
/*108*/ uint32 unknown701;
/*112*/ uint32 unknown702;
/*116*/ uint32 unknown703;
/*120*/ uint32 unknown704;
/*124*/ uint32 ticsremaining[BUFF_COUNT];
/*224*/ uchar unknown705[20];
/*004*/ uint32 spellid[BUFF_COUNT+5];
/*124*/ int32 ticsremaining[BUFF_COUNT+5];
/*244*/ uint32 buffcount;
};
@@ -727,6 +726,7 @@ struct AA_Array
{
uint32 AA;
uint32 value;
uint32 charges;
};
@@ -756,29 +756,46 @@ struct Tribute_Struct {
uint32 tier;
};
//len = 72
struct BandolierItem_Struct {
uint32 item_id;
uint32 icon;
char item_name[64];
};
//len = 320
enum { //bandolier item positions
bandolierMainHand = 0,
bandolierOffHand,
// Bandolier item positions
enum
{
bandolierPrimary = 0,
bandolierSecondary,
bandolierRange,
bandolierAmmo
};
struct Bandolier_Struct {
char name[32];
BandolierItem_Struct items[EmuConstants::BANDOLIER_SIZE];
};
struct PotionBelt_Struct {
BandolierItem_Struct items[EmuConstants::POTION_BELT_SIZE];
//len = 72
struct BandolierItem_Struct
{
uint32 ID;
uint32 Icon;
char Name[64];
};
struct MovePotionToBelt_Struct {
//len = 320
struct Bandolier_Struct
{
char Name[32];
BandolierItem_Struct Items[EmuConstants::BANDOLIER_ITEM_COUNT];
};
//len = 72
struct PotionBeltItem_Struct
{
uint32 ID;
uint32 Icon;
char Name[64];
};
//len = 288
struct PotionBelt_Struct
{
PotionBeltItem_Struct Items[EmuConstants::POTION_BELT_ITEM_COUNT];
};
struct MovePotionToBelt_Struct
{
uint32 Action;
uint32 SlotNumber;
uint32 ItemID;
@@ -1103,7 +1120,7 @@ struct PlayerProfile_Struct
/*12800*/ uint32 expAA;
/*12804*/ uint32 aapoints; //avaliable, unspent
/*12808*/ uint8 unknown12844[36];
/*12844*/ Bandolier_Struct bandoliers[EmuConstants::BANDOLIERS_COUNT];
/*12844*/ Bandolier_Struct bandoliers[EmuConstants::BANDOLIERS_SIZE];
/*14124*/ uint8 unknown14160[4506];
/*18630*/ SuspendedMinion_Struct SuspendedMinion; // No longer in use
/*19240*/ uint32 timeentitledonaccount;
@@ -1144,7 +1161,7 @@ struct TargetReject_Struct {
struct PetCommand_Struct {
/*000*/ uint32 command;
/*004*/ uint32 unknown;
/*004*/ uint32 target;
};
/*
@@ -1249,7 +1266,7 @@ struct ZoneChange_Struct {
// Whatever you send to the client in RequestClientZoneChange_Struct.type, the client will send back
// to the server in ZoneChange_Struct.zone_reason. My guess is this is a memo field of sorts.
// WildcardX 27 January 2008
// 27 January 2008
struct RequestClientZoneChange_Struct {
/*00*/ uint16 zone_id;
@@ -1263,8 +1280,8 @@ struct RequestClientZoneChange_Struct {
struct Animation_Struct {
/*00*/ uint16 spawnid;
/*02*/ uint8 action;
/*03*/ uint8 value;
/*02*/ uint8 speed;
/*03*/ uint8 action;
/*04*/
};
@@ -1302,9 +1319,9 @@ struct CombatDamage_Struct
/* 04 */ uint8 type; //slashing, etc. 231 (0xE7) for spells
/* 05 */ uint16 spellid;
/* 07 */ uint32 damage;
/* 11 */ uint32 unknown11;
/* 15 */ uint32 sequence; // see above notes in Action_Struct
/* 19 */ uint32 unknown19;
/* 11 */ float force;
/* 15 */ float meleepush_xy; // see above notes in Action_Struct
/* 19 */ float meleepush_z;
/* 23 */
};
@@ -2132,24 +2149,24 @@ struct Illusion_Struct_Old {
// OP_Sound - Size: 68
struct QuestReward_Struct
{
/*000*/ uint32 from_mob; // ID of mob awarding the client
/*004*/ uint32 unknown004;
/*008*/ uint32 unknown008;
/*012*/ uint32 unknown012;
/*016*/ uint32 unknown016;
/*020*/ uint32 unknown020;
/*024*/ uint32 silver; // Gives silver to the client
/*028*/ uint32 gold; // Gives gold to the client
/*032*/ uint32 platinum; // Gives platinum to the client
/*036*/ uint32 unknown036;
/*040*/ uint32 unknown040;
/*044*/ uint32 unknown044;
/*048*/ uint32 unknown048;
/*052*/ uint32 unknown052;
/*056*/ uint32 unknown056;
/*060*/ uint32 unknown060;
/*064*/ uint32 unknown064;
/*068*/
/*000*/ uint32 mob_id; // ID of mob awarding the client
/*004*/ uint32 target_id;
/*008*/ uint32 exp_reward;
/*012*/ uint32 faction;
/*016*/ int32 faction_mod;
/*020*/ uint32 copper; // Gives copper to the client
/*024*/ uint32 silver; // Gives silver to the client
/*028*/ uint32 gold; // Gives gold to the client
/*032*/ uint32 platinum; // Gives platinum to the client
/*036*/ uint32 item_id;
/*040*/ uint32 unknown040;
/*044*/ uint32 unknown044;
/*048*/ uint32 unknown048;
/*052*/ uint32 unknown052;
/*056*/ uint32 unknown056;
/*060*/ uint32 unknown060;
/*064*/ uint32 unknown064;
/*068*/
};
// Size: 8
@@ -2405,11 +2422,11 @@ struct InspectResponse_Struct {
/*004*/ uint32 playerid;
/*008*/ char itemnames[23][64];
/*1480*/uint32 itemicons[23];
/*1572*/char text[288]; // Max number of chars in Inspect Window appears to be 254 // Msg struct property is 256 (254 + '\0' is my guess) -U
/*1572*/char text[288]; // Max number of chars in Inspect Window appears to be 254 // Msg struct property is 256 (254 + '\0' is my guess)
/*1860*/
};
//OP_InspectMessageUpdate - Size: 256 (SoF+ clients after self-inspect window is closed) -U
//OP_InspectMessageUpdate - Size: 256 (SoF+ clients after self-inspect window is closed)
struct InspectMessage_Struct {
/*000*/ char text[256];
/*256*/
@@ -2518,9 +2535,9 @@ struct BookRequest_Struct {
**
*/
struct Object_Struct {
/*00*/ uint32 linked_list_addr[2];// <Zaphod> They are, get this, prev and next, ala linked list
/*08*/ uint16 unknown008; //
/*10*/ uint16 unknown010; //
/*00*/ uint32 linked_list_addr[2];// They are, get this, prev and next, ala linked list
/*08*/ uint16 size; //
/*10*/ uint16 solidtype; //
/*12*/ uint32 drop_id; // Unique object id for zone
/*16*/ uint16 zone_id; // Redudant, but: Zone the object appears in
/*18*/ uint16 zone_instance; //
@@ -2537,8 +2554,8 @@ struct Object_Struct {
/*88*/ uint32 spawn_id; // Spawn Id of client interacting with object
/*92*/
};
//<Zaphod> 01 = generic drop, 02 = armor, 19 = weapon
//[13:40] <Zaphod> and 0xff seems to be indicative of the tradeskill/openable items that end up returning the old style item type in the OP_OpenObject
// 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
/*
** Click Object Struct
@@ -2595,7 +2612,7 @@ struct CloseContainer_Struct {
*/
struct Door_Struct
{
/*0000*/ char name[32]; // Filename of Door // Was 10char long before... added the 6 in the next unknown to it: Daeken M. BlackBlade //changed both to 32: Trevius
/*0000*/ char name[32]; // Filename of Door // Was 10char long before... added the 6 in the next unknown to it //changed both to 32
/*0032*/ float yPos; // y loc
/*0036*/ float xPos; // x loc
/*0040*/ float zPos; // z loc
@@ -2761,7 +2778,8 @@ struct BazaarWelcome_Struct {
BazaarWindowStart_Struct Beginning;
uint32 Traders;
uint32 Items;
uint8 Unknown012[8];
uint32 Unknown012;
uint32 Unknown016;
};
struct BazaarSearch_Struct {
@@ -3146,6 +3164,7 @@ struct Trader_ShowItems_Struct{
/*000*/ uint32 Code;
/*004*/ uint32 TraderID;
/*008*/ uint32 Unknown08[3];
/*020*/
};
struct TraderBuy_Struct{
@@ -3191,9 +3210,10 @@ struct TraderDelItem_Struct{
struct TraderClick_Struct{
/*000*/ uint32 TraderID;
/*004*/ uint32 Unknown004;
/*004*/ uint32 Code;
/*008*/ uint32 Unknown008;
/*012*/ uint32 Approval;
/*016*/
};
struct FormattedMessage_Struct{
@@ -4011,7 +4031,7 @@ struct MarkNPC_Struct
struct InspectBuffs_Struct {
/*000*/ uint32 spell_id[BUFF_COUNT];
/*100*/ uint32 tics_remaining[BUFF_COUNT];
/*100*/ int32 tics_remaining[BUFF_COUNT];
};
struct RaidGeneral_Struct {
@@ -4104,30 +4124,35 @@ struct DynamicWall_Struct {
/*80*/
};
enum { //bandolier actions
BandolierCreate = 0,
BandolierRemove = 1,
BandolierSet = 2
// Bandolier actions
enum
{
bandolierCreate = 0,
bandolierRemove,
bandolierSet
};
struct BandolierCreate_Struct {
/*00*/ uint32 action; //0 for create
/*04*/ uint8 number;
/*05*/ char name[32];
/*37*/ uint16 unknown37; //seen 0x93FD
/*39*/ uint8 unknown39; //0
struct BandolierCreate_Struct
{
/*00*/ uint32 Action; //0 for create
/*04*/ uint8 Number;
/*05*/ char Name[32];
/*37*/ uint16 Unknown37; //seen 0x93FD
/*39*/ uint8 Unknown39; //0
};
struct BandolierDelete_Struct {
/*00*/ uint32 action;
/*04*/ uint8 number;
/*05*/ uint8 unknown05[35];
struct BandolierDelete_Struct
{
/*00*/ uint32 Action;
/*04*/ uint8 Number;
/*05*/ uint8 Unknown05[35];
};
struct BandolierSet_Struct {
/*00*/ uint32 action;
/*04*/ uint8 number;
/*05*/ uint8 unknown05[35];
struct BandolierSet_Struct
{
/*00*/ uint32 Action;
/*04*/ uint8 Number;
/*05*/ uint8 Unknown05[35];
};
struct Arrow_Struct {
@@ -4252,14 +4277,6 @@ struct AA_Action {
/*12*/ uint32 exp_value;
};
struct AA_Skills { //this should be removed and changed to AA_Array
/*00*/ uint32 aa_skill; // Total AAs Spent
/*04*/ uint32 aa_value;
/*08*/ uint32 unknown08;
/*12*/
};
struct AAExpUpdate_Struct {
/*00*/ uint32 unknown00; //seems to be a value from AA_Action.ability
/*04*/ uint32 aapoints_unspent;
@@ -4277,12 +4294,12 @@ struct AltAdvStats_Struct {
};
struct PlayerAA_Struct { // Is this still used?
AA_Skills aa_list[MAX_PP_AA_ARRAY];
AA_Array aa_list[MAX_PP_AA_ARRAY];
};
struct AATable_Struct {
/*00*/ int32 aa_spent; // Total AAs Spent
/*04*/ AA_Skills aa_list[MAX_PP_AA_ARRAY];
/*04*/ AA_Array aa_list[MAX_PP_AA_ARRAY];
};
struct Weather_Struct {
@@ -4530,19 +4547,12 @@ struct InternalVeteranReward
/*012*/ InternalVeteranRewardItem items[8];
};
struct VeteranClaimReply
struct VeteranClaim
{
/*000*/ char name[64];
/*064*/ uint32 claim_id;
/*068*/ uint32 reject_field;
/*072*/ uint32 unknown072;
};
struct VeteranClaimRequest
{
/*000*/ char name_data[64]; //name + other data
/*000*/ char name[64]; //name + other data
/*064*/ uint32 claim_id;
/*068*/ uint32 unknown068;
/*072*/ uint32 action;
};
struct GMSearchCorpse_Struct
@@ -4714,7 +4724,7 @@ struct BuffIconEntry_Struct
{
uint32 buff_slot;
uint32 spell_id;
uint32 tics_remaining;
int32 tics_remaining;
uint32 num_hits;
};
@@ -4723,6 +4733,7 @@ struct BuffIcon_Struct
uint32 entity_id;
uint8 all_buffs;
uint16 count;
uint8 type; // 0 = self buff window, 1 = self target window, 4 = group, 5 = PC, 7 = NPC
BuffIconEntry_Struct entries[0];
};
+78 -106
View File
@@ -50,7 +50,6 @@
uint16 EQStream::MaxWindowSize=2048;
void EQStream::init(bool resetSession) {
_eqp
// we only reset these statistics if it is a 'new' connection
if ( resetSession )
{
@@ -73,6 +72,8 @@ void EQStream::init(bool resetSession) {
RateThreshold=RATEBASE/250;
DecayRate=DECAYBASE/250;
BytesWritten=0;
sent_packet_count = 0;
received_packet_count = 0;
SequencedBase = 0;
NextSequencedSend = 0;
@@ -93,7 +94,6 @@ void EQStream::init(bool resetSession) {
EQRawApplicationPacket *EQStream::MakeApplicationPacket(EQProtocolPacket *p)
{
_eqp
EQRawApplicationPacket *ap=nullptr;
Log.Out(Logs::Detail, Logs::Netcode, _L "Creating new application packet, length %d" __L, p->size);
// _raw(NET__APP_CREATE_HEX, 0xFFFF, p);
@@ -103,7 +103,6 @@ EQRawApplicationPacket *EQStream::MakeApplicationPacket(EQProtocolPacket *p)
EQRawApplicationPacket *EQStream::MakeApplicationPacket(const unsigned char *buf, uint32 len)
{
_eqp
EQRawApplicationPacket *ap=nullptr;
Log.Out(Logs::Detail, Logs::Netcode, _L "Creating new application packet, length %d" __L, len);
ap = new EQRawApplicationPacket(buf, len);
@@ -111,7 +110,6 @@ EQRawApplicationPacket *EQStream::MakeApplicationPacket(const unsigned char *buf
}
EQProtocolPacket *EQStream::MakeProtocolPacket(const unsigned char *buf, uint32 len) {
_eqp
uint16 proto_opcode = ntohs(*(const uint16 *)buf);
//advance over opcode.
@@ -123,7 +121,6 @@ EQProtocolPacket *EQStream::MakeProtocolPacket(const unsigned char *buf, uint32
void EQStream::ProcessPacket(EQProtocolPacket *p)
{
_eqp
uint32 processed=0, subpacket_length=0;
if (p == nullptr)
return;
@@ -469,37 +466,45 @@ void EQStream::ProcessPacket(EQProtocolPacket *p)
}
break;
case OP_SessionStatRequest: {
if(p->Size() < sizeof(SessionStats))
if(p->Size() < sizeof(ClientSessionStats))
{
Log.Out(Logs::Detail, Logs::Netcode, _L "Received OP_SessionStatRequest that was of malformed size" __L);
break;
}
#ifndef COLLECTOR
SessionStats *Stats=(SessionStats *)p->pBuffer;
ClientSessionStats *ClientStats=(ClientSessionStats *)p->pBuffer;
Log.Out(Logs::Detail, Logs::Netcode, _L "Received Stats: %lu packets received, %lu packets sent, Deltas: local %lu, (%lu <- %lu -> %lu) remote %lu" __L,
(unsigned long)ntohl(Stats->packets_received), (unsigned long)ntohl(Stats->packets_sent), (unsigned long)ntohl(Stats->last_local_delta),
(unsigned long)ntohl(Stats->low_delta), (unsigned long)ntohl(Stats->average_delta),
(unsigned long)ntohl(Stats->high_delta), (unsigned long)ntohl(Stats->last_remote_delta));
uint64 x=Stats->packets_received;
Stats->packets_received=Stats->packets_sent;
Stats->packets_sent=x;
NonSequencedPush(new EQProtocolPacket(OP_SessionStatResponse,p->pBuffer,p->size));
AdjustRates(ntohl(Stats->average_delta));
(unsigned long)ntohl(ClientStats->packets_received), (unsigned long)ntohl(ClientStats->packets_sent), (unsigned long)ntohl(ClientStats->last_local_delta),
(unsigned long)ntohl(ClientStats->low_delta), (unsigned long)ntohl(ClientStats->average_delta),
(unsigned long)ntohl(ClientStats->high_delta), (unsigned long)ntohl(ClientStats->last_remote_delta));
AdjustRates(ntohl(ClientStats->average_delta));
if(GetExecutablePlatform() == ExePlatformWorld || GetExecutablePlatform() == ExePlatformZone) {
if(RETRANSMIT_TIMEOUT_MULT && ntohl(Stats->average_delta)) {
if (RETRANSMIT_TIMEOUT_MULT && ntohl(ClientStats->average_delta)) {
//recalculate retransmittimeout using the larger of the last rtt or average rtt, which is multiplied by the rule value
if((ntohl(Stats->last_local_delta) + ntohl(Stats->last_remote_delta)) > (ntohl(Stats->average_delta) * 2)) {
retransmittimeout = (ntohl(Stats->last_local_delta) + ntohl(Stats->last_remote_delta))
if ((ntohl(ClientStats->last_local_delta) + ntohl(ClientStats->last_remote_delta)) > (ntohl(ClientStats->average_delta) * 2)) {
retransmittimeout = (ntohl(ClientStats->last_local_delta) + ntohl(ClientStats->last_remote_delta))
* RETRANSMIT_TIMEOUT_MULT;
} else {
retransmittimeout = ntohl(Stats->average_delta) * 2 * RETRANSMIT_TIMEOUT_MULT;
retransmittimeout = ntohl(ClientStats->average_delta) * 2 * RETRANSMIT_TIMEOUT_MULT;
}
if(retransmittimeout > RETRANSMIT_TIMEOUT_MAX)
retransmittimeout = RETRANSMIT_TIMEOUT_MAX;
Log.Out(Logs::Detail, Logs::Netcode, _L "Retransmit timeout recalculated to %dms" __L, retransmittimeout);
}
}
ServerSessionStats *ServerStats = (ServerSessionStats *)p->pBuffer;
//ServerStats->RequestID = ClientStats->RequestID; // no change
ServerStats->ServerTime = htonl(Timer::GetCurrentTime());
ServerStats->packets_sent_echo = ClientStats->packets_sent; // still in htonll format
ServerStats->packets_received_echo = ClientStats->packets_received; // still in htonll format
ServerStats->packets_sent = htonll(GetPacketsSent());
ServerStats->packets_received = htonll(GetPacketsReceived());
NonSequencedPush(new EQProtocolPacket(OP_SessionStatResponse, p->pBuffer, p->size));
#endif
}
break;
@@ -521,7 +526,6 @@ void EQStream::ProcessPacket(EQProtocolPacket *p)
void EQStream::QueuePacket(const EQApplicationPacket *p, bool ack_req)
{
_eqp
if(p == nullptr)
return;
@@ -533,7 +537,6 @@ void EQStream::QueuePacket(const EQApplicationPacket *p, bool ack_req)
void EQStream::FastQueuePacket(EQApplicationPacket **p, bool ack_req)
{
_eqp
EQApplicationPacket *pack=*p;
*p = nullptr; //clear caller's pointer.. effectively takes ownership
@@ -563,7 +566,6 @@ void EQStream::FastQueuePacket(EQApplicationPacket **p, bool ack_req)
void EQStream::SendPacket(uint16 opcode, EQApplicationPacket *p)
{
_eqp
uint32 chunksize, used;
uint32 length;
@@ -581,16 +583,18 @@ void EQStream::SendPacket(uint16 opcode, EQApplicationPacket *p)
// Convert the EQApplicationPacket to 1 or more EQProtocolPackets
if (p->size>(MaxLen-8)) { // proto-op(2), seq(2), app-op(2) ... data ... crc(2)
Log.Out(Logs::Detail, Logs::Netcode, _L "Making oversized packet, len %d" __L, p->size);
Log.Out(Logs::Detail, Logs::Netcode, _L "Making oversized packet, len %d" __L, p->Size());
unsigned char *tmpbuff=new unsigned char[p->size+3];
length=p->serialize(opcode, tmpbuff);
if (length != p->Size())
Log.Out(Logs::Detail, Logs::Netcode, _L "Packet adjustment, len %d to %d" __L, p->Size(), length);
EQProtocolPacket *out=new EQProtocolPacket(OP_Fragment,nullptr,MaxLen-4);
*(uint32 *)(out->pBuffer+2)=htonl(p->Size());
*(uint32 *)(out->pBuffer+2)=htonl(length);
used=MaxLen-10;
memcpy(out->pBuffer+6,tmpbuff,used);
Log.Out(Logs::Detail, Logs::Netcode, _L "First fragment: used %d/%d. Put size %d in the packet" __L, used, p->size, p->Size());
Log.Out(Logs::Detail, Logs::Netcode, _L "First fragment: used %d/%d. Payload size %d in the packet" __L, used, length, p->size);
SequencedPush(out);
@@ -601,7 +605,7 @@ void EQStream::SendPacket(uint16 opcode, EQApplicationPacket *p)
out->size=chunksize+2;
SequencedPush(out);
used+=chunksize;
Log.Out(Logs::Detail, Logs::Netcode, _L "Subsequent fragment: len %d, used %d/%d." __L, chunksize, used, p->size);
Log.Out(Logs::Detail, Logs::Netcode, _L "Subsequent fragment: len %d, used %d/%d." __L, chunksize, used, length);
}
delete p;
delete[] tmpbuff;
@@ -620,36 +624,34 @@ void EQStream::SendPacket(uint16 opcode, EQApplicationPacket *p)
void EQStream::SequencedPush(EQProtocolPacket *p)
{
_eqp
#ifdef COLLECTOR
delete p;
#else
MOutboundQueue.lock();
if(uint16(SequencedBase + SequencedQueue.size()) != NextOutSeq) {
Log.Out(Logs::Detail, Logs::Netcode, _L "Pre-Push Invalid Sequenced queue: BS %d + SQ %d != NOS %d" __L, SequencedBase, SequencedQueue.size(), NextOutSeq);
}
if(NextSequencedSend > SequencedQueue.size()) {
Log.Out(Logs::Detail, Logs::Netcode, _L "Pre-Push Next Send Sequence is beyond the end of the queue NSS %d > SQ %d" __L, NextSequencedSend, SequencedQueue.size());
}
if(uint16(SequencedBase + SequencedQueue.size()) != NextOutSeq) {
Log.Out(Logs::Detail, Logs::Netcode, _L "Pre-Push Invalid Sequenced queue: BS %d + SQ %d != NOS %d" __L, SequencedBase, SequencedQueue.size(), NextOutSeq);
}
if(NextSequencedSend > SequencedQueue.size()) {
Log.Out(Logs::Detail, Logs::Netcode, _L "Pre-Push Next Send Sequence is beyond the end of the queue NSS %d > SQ %d" __L, NextSequencedSend, SequencedQueue.size());
}
Log.Out(Logs::Detail, Logs::Netcode, _L "Pushing sequenced packet %d of length %d. Base Seq is %d." __L, NextOutSeq, p->size, SequencedBase);
*(uint16 *)(p->pBuffer)=htons(NextOutSeq);
SequencedQueue.push_back(p);
NextOutSeq++;
if(uint16(SequencedBase + SequencedQueue.size()) != NextOutSeq) {
Log.Out(Logs::Detail, Logs::Netcode, _L "Push Invalid Sequenced queue: BS %d + SQ %d != NOS %d" __L, SequencedBase, SequencedQueue.size(), NextOutSeq);
}
if(NextSequencedSend > SequencedQueue.size()) {
Log.Out(Logs::Detail, Logs::Netcode, _L "Push Next Send Sequence is beyond the end of the queue NSS %d > SQ %d" __L, NextSequencedSend, SequencedQueue.size());
}
if(uint16(SequencedBase + SequencedQueue.size()) != NextOutSeq) {
Log.Out(Logs::Detail, Logs::Netcode, _L "Push Invalid Sequenced queue: BS %d + SQ %d != NOS %d" __L, SequencedBase, SequencedQueue.size(), NextOutSeq);
}
if(NextSequencedSend > SequencedQueue.size()) {
Log.Out(Logs::Detail, Logs::Netcode, _L "Push Next Send Sequence is beyond the end of the queue NSS %d > SQ %d" __L, NextSequencedSend, SequencedQueue.size());
}
MOutboundQueue.unlock();
#endif
}
void EQStream::NonSequencedPush(EQProtocolPacket *p)
{
_eqp
#ifdef COLLECTOR
delete p;
#else
@@ -662,8 +664,7 @@ void EQStream::NonSequencedPush(EQProtocolPacket *p)
void EQStream::SendAck(uint16 seq)
{
_eqp
uint16 Seq=htons(seq);
uint16 Seq=htons(seq);
Log.Out(Logs::Detail, Logs::Netcode, _L "Sending ack with sequence %d" __L, seq);
SetLastAckSent(seq);
NonSequencedPush(new EQProtocolPacket(OP_Ack,(unsigned char *)&Seq,sizeof(uint16)));
@@ -671,9 +672,8 @@ void EQStream::SendAck(uint16 seq)
void EQStream::SendOutOfOrderAck(uint16 seq)
{
_eqp
Log.Out(Logs::Detail, Logs::Netcode, _L "Sending out of order ack with sequence %d" __L, seq);
uint16 Seq=htons(seq);
uint16 Seq=htons(seq);
NonSequencedPush(new EQProtocolPacket(OP_OutOfOrderAck,(unsigned char *)&Seq,sizeof(uint16)));
}
@@ -874,9 +874,8 @@ void EQStream::Write(int eq_fd)
void EQStream::WritePacket(int eq_fd, EQProtocolPacket *p)
{
_eqp
uint32 length;
sockaddr_in address;
uint32 length;
sockaddr_in address;
address.sin_family = AF_INET;
address.sin_addr.s_addr=remote_ip;
address.sin_port=remote_port;
@@ -913,8 +912,7 @@ void EQStream::WritePacket(int eq_fd, EQProtocolPacket *p)
void EQStream::SendSessionResponse()
{
_eqp
EQProtocolPacket *out=new EQProtocolPacket(OP_SessionResponse,nullptr,sizeof(SessionResponse));
EQProtocolPacket *out=new EQProtocolPacket(OP_SessionResponse,nullptr,sizeof(SessionResponse));
SessionResponse *Response=(SessionResponse *)out->pBuffer;
Response->Session=htonl(Session);
Response->MaxLength=htonl(MaxLen);
@@ -936,8 +934,7 @@ void EQStream::SendSessionResponse()
void EQStream::SendSessionRequest()
{
_eqp
EQProtocolPacket *out=new EQProtocolPacket(OP_SessionRequest,nullptr,sizeof(SessionRequest));
EQProtocolPacket *out=new EQProtocolPacket(OP_SessionRequest,nullptr,sizeof(SessionRequest));
SessionRequest *Request=(SessionRequest *)out->pBuffer;
memset(Request,0,sizeof(SessionRequest));
Request->Session=htonl(time(nullptr));
@@ -950,7 +947,6 @@ void EQStream::SendSessionRequest()
void EQStream::_SendDisconnect()
{
_eqp
if(GetState() == CLOSED)
return;
@@ -963,7 +959,6 @@ void EQStream::_SendDisconnect()
void EQStream::InboundQueuePush(EQRawApplicationPacket *p)
{
_eqp
MInboundQueue.lock();
InboundQueue.push_back(p);
MInboundQueue.unlock();
@@ -971,8 +966,7 @@ void EQStream::InboundQueuePush(EQRawApplicationPacket *p)
EQApplicationPacket *EQStream::PopPacket()
{
_eqp
EQRawApplicationPacket *p=nullptr;
EQRawApplicationPacket *p=nullptr;
MInboundQueue.lock();
if (InboundQueue.size()) {
@@ -997,8 +991,7 @@ EQApplicationPacket *EQStream::PopPacket()
EQRawApplicationPacket *EQStream::PopRawPacket()
{
_eqp
EQRawApplicationPacket *p=nullptr;
EQRawApplicationPacket *p=nullptr;
MInboundQueue.lock();
if (InboundQueue.size()) {
@@ -1025,8 +1018,7 @@ EQRawApplicationPacket *EQStream::PopRawPacket()
EQRawApplicationPacket *EQStream::PeekPacket()
{
_eqp
EQRawApplicationPacket *p=nullptr;
EQRawApplicationPacket *p=nullptr;
MInboundQueue.lock();
if (InboundQueue.size()) {
@@ -1040,8 +1032,7 @@ EQRawApplicationPacket *EQStream::PeekPacket()
void EQStream::InboundQueueClear()
{
_eqp
EQApplicationPacket *p=nullptr;
EQApplicationPacket *p=nullptr;
Log.Out(Logs::Detail, Logs::Netcode, _L "Clearing inbound queue" __L);
@@ -1059,8 +1050,7 @@ void EQStream::InboundQueueClear()
bool EQStream::HasOutgoingData()
{
_eqp
bool flag;
bool flag;
//once closed, we have nothing more to say
if(CheckClosed())
@@ -1085,8 +1075,7 @@ bool EQStream::HasOutgoingData()
void EQStream::OutboundQueueClear()
{
_eqp
EQProtocolPacket *p=nullptr;
EQProtocolPacket *p=nullptr;
Log.Out(Logs::Detail, Logs::Netcode, _L "Clearing outbound queue" __L);
@@ -1108,8 +1097,7 @@ void EQStream::OutboundQueueClear()
void EQStream::PacketQueueClear()
{
_eqp
EQProtocolPacket *p=nullptr;
EQProtocolPacket *p=nullptr;
Log.Out(Logs::Detail, Logs::Netcode, _L "Clearing future packet queue" __L);
@@ -1125,7 +1113,6 @@ void EQStream::PacketQueueClear()
void EQStream::Process(const unsigned char *buffer, const uint32 length)
{
_eqp
static unsigned char newbuffer[2048];
uint32 newlength=0;
if (EQProtocolPacket::ValidateCRC(buffer,length,Key)) {
@@ -1150,7 +1137,6 @@ void EQStream::Process(const unsigned char *buffer, const uint32 length)
long EQStream::GetNextAckToSend()
{
_eqp
MAcks.lock();
long l=NextAckToSend;
MAcks.unlock();
@@ -1160,7 +1146,6 @@ long EQStream::GetNextAckToSend()
long EQStream::GetLastAckSent()
{
_eqp
MAcks.lock();
long l=LastAckSent;
MAcks.unlock();
@@ -1170,17 +1155,16 @@ long EQStream::GetLastAckSent()
void EQStream::AckPackets(uint16 seq)
{
_eqp
std::deque<EQProtocolPacket *>::iterator itr, tmp;
std::deque<EQProtocolPacket *>::iterator itr, tmp;
MOutboundQueue.lock();
//do a bit of sanity checking.
if(uint16(SequencedBase + SequencedQueue.size()) != NextOutSeq) {
Log.Out(Logs::Detail, Logs::Netcode, _L "Pre-Ack Invalid Sequenced queue: BS %d + SQ %d != NOS %d" __L, SequencedBase, SequencedQueue.size(), NextOutSeq);
}
if(NextSequencedSend > SequencedQueue.size()) {
Log.Out(Logs::Detail, Logs::Netcode, _L "Pre-Ack Next Send Sequence is beyond the end of the queue NSS %d > SQ %d" __L, NextSequencedSend, SequencedQueue.size());
}
//do a bit of sanity checking.
if(uint16(SequencedBase + SequencedQueue.size()) != NextOutSeq) {
Log.Out(Logs::Detail, Logs::Netcode, _L "Pre-Ack Invalid Sequenced queue: BS %d + SQ %d != NOS %d" __L, SequencedBase, SequencedQueue.size(), NextOutSeq);
}
if(NextSequencedSend > SequencedQueue.size()) {
Log.Out(Logs::Detail, Logs::Netcode, _L "Pre-Ack Next Send Sequence is beyond the end of the queue NSS %d > SQ %d" __L, NextSequencedSend, SequencedQueue.size());
}
SeqOrder ord = CompareSequence(SequencedBase, seq);
if(ord == SeqInOrder) {
@@ -1196,12 +1180,12 @@ void EQStream::AckPackets(uint16 seq)
//this is a good ack, we get to ack some blocks.
seq++; //we stop at the block right after their ack, counting on the wrap of both numbers.
while(SequencedBase != seq) {
if(SequencedQueue.empty()) {
Log.Out(Logs::Detail, Logs::Netcode, _L "OUT OF PACKETS acked packet with sequence %lu. Next send is %d before this." __L, (unsigned long)SequencedBase, NextSequencedSend);
SequencedBase = NextOutSeq;
NextSequencedSend = 0;
break;
}
if(SequencedQueue.empty()) {
Log.Out(Logs::Detail, Logs::Netcode, _L "OUT OF PACKETS acked packet with sequence %lu. Next send is %d before this." __L, (unsigned long)SequencedBase, NextSequencedSend);
SequencedBase = NextOutSeq;
NextSequencedSend = 0;
break;
}
Log.Out(Logs::Detail, Logs::Netcode, _L "Removing acked packet with sequence %lu. Next send is %d before this." __L, (unsigned long)SequencedBase, NextSequencedSend);
//clean out the acked packet
delete SequencedQueue.front();
@@ -1212,12 +1196,12 @@ void EQStream::AckPackets(uint16 seq)
//advance the base sequence number to the seq of the block after the one we just got rid of.
SequencedBase++;
}
if(uint16(SequencedBase + SequencedQueue.size()) != NextOutSeq) {
Log.Out(Logs::Detail, Logs::Netcode, _L "Post-Ack on %d Invalid Sequenced queue: BS %d + SQ %d != NOS %d" __L, seq, SequencedBase, SequencedQueue.size(), NextOutSeq);
}
if(NextSequencedSend > SequencedQueue.size()) {
Log.Out(Logs::Detail, Logs::Netcode, _L "Post-Ack Next Send Sequence is beyond the end of the queue NSS %d > SQ %d" __L, NextSequencedSend, SequencedQueue.size());
}
if(uint16(SequencedBase + SequencedQueue.size()) != NextOutSeq) {
Log.Out(Logs::Detail, Logs::Netcode, _L "Post-Ack on %d Invalid Sequenced queue: BS %d + SQ %d != NOS %d" __L, seq, SequencedBase, SequencedQueue.size(), NextOutSeq);
}
if(NextSequencedSend > SequencedQueue.size()) {
Log.Out(Logs::Detail, Logs::Netcode, _L "Post-Ack Next Send Sequence is beyond the end of the queue NSS %d > SQ %d" __L, NextSequencedSend, SequencedQueue.size());
}
}
MOutboundQueue.unlock();
@@ -1225,7 +1209,6 @@ void EQStream::AckPackets(uint16 seq)
void EQStream::SetNextAckToSend(uint32 seq)
{
_eqp
MAcks.lock();
Log.Out(Logs::Detail, Logs::Netcode, _L "Set Next Ack To Send to %lu" __L, (unsigned long)seq);
NextAckToSend=seq;
@@ -1234,7 +1217,6 @@ void EQStream::SetNextAckToSend(uint32 seq)
void EQStream::SetLastAckSent(uint32 seq)
{
_eqp
MAcks.lock();
Log.Out(Logs::Detail, Logs::Netcode, _L "Set Last Ack Sent to %lu" __L, (unsigned long)seq);
LastAckSent=seq;
@@ -1243,7 +1225,6 @@ void EQStream::SetLastAckSent(uint32 seq)
void EQStream::ProcessQueue()
{
_eqp
if(PacketQueue.empty()) {
return;
}
@@ -1259,9 +1240,8 @@ void EQStream::ProcessQueue()
EQProtocolPacket *EQStream::RemoveQueue(uint16 seq)
{
_eqp
std::map<unsigned short,EQProtocolPacket *>::iterator itr;
EQProtocolPacket *qp=nullptr;
std::map<unsigned short,EQProtocolPacket *>::iterator itr;
EQProtocolPacket *qp=nullptr;
if ((itr=PacketQueue.find(seq))!=PacketQueue.end()) {
qp=itr->second;
PacketQueue.erase(itr);
@@ -1272,7 +1252,6 @@ EQProtocolPacket *EQStream::RemoveQueue(uint16 seq)
void EQStream::SetStreamType(EQStreamType type)
{
_eqp
Log.Out(Logs::Detail, Logs::Netcode, _L "Changing stream type from %s to %s" __L, StreamTypeString(StreamType), StreamTypeString(type));
StreamType=type;
switch (StreamType) {
@@ -1303,7 +1282,6 @@ void EQStream::SetStreamType(EQStreamType type)
const char *EQStream::StreamTypeString(EQStreamType t)
{
_eqp
switch (t) {
case LoginStream:
return "Login";
@@ -1333,7 +1311,6 @@ const char *EQStream::StreamTypeString(EQStreamType t)
//returns SeqFuture if `seq` is later than `expected_seq`
EQStream::SeqOrder EQStream::CompareSequence(uint16 expected_seq , uint16 seq)
{
_eqp
if (expected_seq==seq) {
// Curent
return SeqInOrder;
@@ -1347,7 +1324,6 @@ EQStream::SeqOrder EQStream::CompareSequence(uint16 expected_seq , uint16 seq)
}
void EQStream::SetState(EQStreamState state) {
_eqp
MState.lock();
Log.Out(Logs::Detail, Logs::Netcode, _L "Changing state from %d to %d" __L, State, state);
State=state;
@@ -1356,7 +1332,7 @@ void EQStream::SetState(EQStreamState state) {
void EQStream::CheckTimeout(uint32 now, uint32 timeout) {
_eqp
bool outgoing_data = HasOutgoingData(); //up here to avoid recursive locking
EQStreamState orig_state = GetState();
@@ -1395,7 +1371,6 @@ void EQStream::CheckTimeout(uint32 now, uint32 timeout) {
void EQStream::Decay()
{
_eqp
MRate.lock();
uint32 rate=DecayRate;
MRate.unlock();
@@ -1408,7 +1383,6 @@ void EQStream::Decay()
void EQStream::AdjustRates(uint32 average_delta)
{
_eqp
if(GetExecutablePlatform() == ExePlatformWorld || GetExecutablePlatform() == ExePlatformZone) {
if (average_delta && (average_delta <= AVERAGE_DELTA_MAX)) {
MRate.lock();
@@ -1434,7 +1408,6 @@ void EQStream::AdjustRates(uint32 average_delta)
}
void EQStream::Close() {
_eqp
if(HasOutgoingData()) {
//there is pending data, wait for it to go out.
Log.Out(Logs::Detail, Logs::Netcode, _L "Stream requested to Close(), but there is pending data, waiting for it." __L);
@@ -1451,7 +1424,6 @@ void EQStream::Close() {
//this could be expanded to check more than the fitst opcode if
//we needed more complex matching
EQStream::MatchState EQStream::CheckSignature(const Signature *sig) {
_eqp
EQRawApplicationPacket *p = nullptr;
MatchState res = MatchNotReady;
+19 -1
View File
@@ -71,7 +71,7 @@ struct SessionResponse {
};
//Deltas are in ms, representing round trip times
struct SessionStats {
struct ClientSessionStats {
/*000*/ uint16 RequestID;
/*002*/ uint32 last_local_delta;
/*006*/ uint32 average_delta;
@@ -83,6 +83,16 @@ struct SessionStats {
/*038*/
};
struct ServerSessionStats {
/*000*/ uint16 RequestID;
/*002*/ uint32 ServerTime;
/*006*/ uint64 packets_sent_echo;
/*014*/ uint64 packets_received_echo;
/*022*/ uint64 packets_sent;
/*030*/ uint64 packets_received;
/*038*/
};
#pragma pack()
class OpcodeManager;
@@ -158,6 +168,9 @@ class EQStream : public EQStreamInterface {
int32 BytesWritten;
uint64 sent_packet_count;
uint64 received_packet_count;
Mutex MRate;
int32 RateThreshold;
int32 DecayRate;
@@ -265,11 +278,13 @@ class EQStream : public EQStreamInterface {
void AddBytesSent(uint32 bytes)
{
bytes_sent += bytes;
++sent_packet_count;
}
void AddBytesRecv(uint32 bytes)
{
bytes_recv += bytes;
++received_packet_count;
}
virtual const uint32 GetBytesSent() const { return bytes_sent; }
@@ -288,6 +303,9 @@ class EQStream : public EQStreamInterface {
return bytes_recv / (Timer::GetTimeSeconds() - create_time);
}
const uint64 GetPacketsSent() { return sent_packet_count; }
const uint64 GetPacketsReceived() { return received_packet_count; }
//used for dynamic stream identification
class Signature {
public:
+3 -13
View File
@@ -23,8 +23,7 @@
ThreadReturnType EQStreamFactoryReaderLoop(void *eqfs)
{
_eqp
EQStreamFactory *fs = (EQStreamFactory*)eqfs;
EQStreamFactory *fs=(EQStreamFactory *)eqfs;
#ifndef WIN32
Log.Out(Logs::Detail, Logs::None, "Starting EQStreamFactoryReaderLoop with thread ID %d", pthread_self());
@@ -41,8 +40,7 @@ ThreadReturnType EQStreamFactoryReaderLoop(void *eqfs)
ThreadReturnType EQStreamFactoryWriterLoop(void *eqfs)
{
_eqp
EQStreamFactory *fs = (EQStreamFactory*)eqfs;
EQStreamFactory *fs=(EQStreamFactory *)eqfs;
#ifndef WIN32
Log.Out(Logs::Detail, Logs::None, "Starting EQStreamFactoryWriterLoop with thread ID %d", pthread_self());
@@ -60,7 +58,6 @@ ThreadReturnType EQStreamFactoryWriterLoop(void *eqfs)
EQStreamFactory::EQStreamFactory(EQStreamType type, int port, uint32 timeout)
: Timeoutable(5000), stream_timeout(timeout)
{
_eqp
StreamType=type;
Port=port;
sock=-1;
@@ -68,7 +65,6 @@ EQStreamFactory::EQStreamFactory(EQStreamType type, int port, uint32 timeout)
void EQStreamFactory::Close()
{
_eqp
Stop();
#ifdef _WINDOWS
@@ -81,8 +77,7 @@ void EQStreamFactory::Close()
bool EQStreamFactory::Open()
{
_eqp
struct sockaddr_in address;
struct sockaddr_in address;
#ifndef WIN32
pthread_t t1,t2;
#endif
@@ -123,7 +118,6 @@ bool EQStreamFactory::Open()
std::shared_ptr<EQStream> EQStreamFactory::Pop()
{
_eqp
std::shared_ptr<EQStream> s = nullptr;
MNewStreams.lock();
if (NewStreams.size()) {
@@ -138,7 +132,6 @@ std::shared_ptr<EQStream> EQStreamFactory::Pop()
void EQStreamFactory::Push(std::shared_ptr<EQStream> s)
{
_eqp
MNewStreams.lock();
NewStreams.push(s);
MNewStreams.unlock();
@@ -146,7 +139,6 @@ void EQStreamFactory::Push(std::shared_ptr<EQStream> s)
void EQStreamFactory::ReaderLoop()
{
_eqp
fd_set readset;
std::map<std::pair<uint32, uint16>, std::shared_ptr<EQStream>>::iterator stream_itr;
int num;
@@ -224,7 +216,6 @@ void EQStreamFactory::ReaderLoop()
void EQStreamFactory::CheckTimeout()
{
_eqp
//lock streams the entire time were checking timeouts, it should be fast.
MStreams.lock();
@@ -259,7 +250,6 @@ void EQStreamFactory::CheckTimeout()
void EQStreamFactory::WriterLoop()
{
_eqp
std::map<std::pair<uint32, uint16>, std::shared_ptr<EQStream>>::iterator stream_itr;
bool havework=true;
std::vector<std::shared_ptr<EQStream>> wants_write;
-11
View File
@@ -28,7 +28,6 @@ EQEmuConfig *EQEmuConfig::_config = nullptr;
void EQEmuConfig::do_world(TiXmlElement *ele)
{
_eqp
const char *text;
TiXmlElement * sub_ele;;
text = ParseTextBlock(ele, "shortname");
@@ -146,7 +145,6 @@ void EQEmuConfig::do_world(TiXmlElement *ele)
void EQEmuConfig::do_chatserver(TiXmlElement *ele)
{
_eqp
const char *text;
text = ParseTextBlock(ele, "host", true);
if (text) {
@@ -160,7 +158,6 @@ void EQEmuConfig::do_chatserver(TiXmlElement *ele)
void EQEmuConfig::do_mailserver(TiXmlElement *ele)
{
_eqp
const char *text;
text = ParseTextBlock(ele, "host", true);
if (text) {
@@ -174,7 +171,6 @@ void EQEmuConfig::do_mailserver(TiXmlElement *ele)
void EQEmuConfig::do_database(TiXmlElement *ele)
{
_eqp
const char *text;
text = ParseTextBlock(ele, "host", true);
if (text) {
@@ -201,7 +197,6 @@ void EQEmuConfig::do_database(TiXmlElement *ele)
void EQEmuConfig::do_qsdatabase(TiXmlElement *ele)
{
_eqp
const char *text;
text = ParseTextBlock(ele, "host", true);
if (text) {
@@ -227,7 +222,6 @@ void EQEmuConfig::do_qsdatabase(TiXmlElement *ele)
void EQEmuConfig::do_zones(TiXmlElement *ele)
{
_eqp
const char *text;
TiXmlElement *sub_ele;
// TiXmlNode *node,*sub_node;
@@ -251,7 +245,6 @@ void EQEmuConfig::do_zones(TiXmlElement *ele)
void EQEmuConfig::do_files(TiXmlElement *ele)
{
_eqp
const char *text;
text = ParseTextBlock(ele, "spells", true);
if (text) {
@@ -269,7 +262,6 @@ void EQEmuConfig::do_files(TiXmlElement *ele)
void EQEmuConfig::do_directories(TiXmlElement *ele)
{
_eqp
const char *text;
text = ParseTextBlock(ele, "maps", true);
if (text) {
@@ -287,7 +279,6 @@ void EQEmuConfig::do_directories(TiXmlElement *ele)
void EQEmuConfig::do_launcher(TiXmlElement *ele)
{
_eqp
const char *text;
TiXmlElement *sub_ele;
text = ParseTextBlock(ele, "logprefix", true);
@@ -327,7 +318,6 @@ void EQEmuConfig::do_launcher(TiXmlElement *ele)
std::string EQEmuConfig::GetByName(const std::string &var_name) const
{
_eqp
if (var_name == "ShortName") {
return (ShortName);
}
@@ -455,7 +445,6 @@ std::string EQEmuConfig::GetByName(const std::string &var_name) const
void EQEmuConfig::Dump() const
{
_eqp
std::cout << "ShortName = " << ShortName << std::endl;
std::cout << "LongName = " << LongName << std::endl;
std::cout << "WorldAddress = " << WorldAddress << std::endl;
+2 -5
View File
@@ -96,7 +96,6 @@ void EQEmuLogSys::LoadLogSettingsDefaults()
memset(log_settings, 0, sizeof(LogSettings) * Logs::LogCategory::MaxCategoryID);
/* Set Defaults */
log_settings[Logs::LoginServer].log_to_console = Logs::General;
log_settings[Logs::World_Server].log_to_console = Logs::General;
log_settings[Logs::Zone_Server].log_to_console = Logs::General;
log_settings[Logs::QS_Server].log_to_console = Logs::General;
@@ -117,7 +116,7 @@ void EQEmuLogSys::LoadLogSettingsDefaults()
platform_file_name = "ucs";
else if (EQEmuLogSys::log_platform == EQEmuExePlatform::ExePlatformLogin)
platform_file_name = "login";
else if (EQEmuLogSys::log_platform == EQEmuExePlatform::ExePlatformLaunch)
else if (EQEmuLogSys::log_platform == EQEmuExePlatform::ExePlatformLogin)
platform_file_name = "launcher";
}
@@ -273,14 +272,12 @@ void EQEmuLogSys::ProcessConsoleMessage(uint16 debug_level, uint16 log_category,
void EQEmuLogSys::Out(Logs::DebugLevel debug_level, uint16 log_category, std::string message, ...)
{
_eqp
const bool log_to_console = log_settings[log_category].log_to_console > 0;
const bool log_to_file = log_settings[log_category].log_to_file > 0;
const bool log_to_gmsay = log_settings[log_category].log_to_gmsay > 0;
const bool nothing_to_log = !log_to_console && !log_to_file && !log_to_gmsay;
if (nothing_to_log)
return;
if (nothing_to_log) return;
va_list args;
va_start(args, message);
+2 -6
View File
@@ -48,14 +48,12 @@ namespace Logs {
Combat,
Commands,
Crash,
Database,
Debug,
Doors,
Error,
Guilds,
Inventory,
Launcher,
LoginServer,
Netcode,
Normal,
Object,
@@ -98,14 +96,12 @@ namespace Logs {
"Combat",
"Commands",
"Crash",
"Database",
"Debug",
"Doors",
"Error",
"Guilds",
"Inventory",
"Launcher",
"LoginServer",
"Netcode",
"Normal",
"Object",
@@ -126,8 +122,8 @@ namespace Logs {
"WebInterface Server",
"World Server",
"Zone Server",
"MySQLError",
"MySQLQuery",
"MySQL Error",
"MySQL Query",
"Mercenaries",
"Quest Debug",
"Packet :: Server -> Client",
+41 -42
View File
@@ -43,19 +43,19 @@ EQTime::EQTime(TimeOfDay_Struct start_eq, time_t start_real)
EQTime::EQTime()
{
timezone=0;
timezone = 0;
memset(&eqTime, 0, sizeof(eqTime));
//Defaults for time
TimeOfDay_Struct start;
start.day=1;
start.hour=9;
start.minute=0;
start.month=1;
start.year=3100;
start.day = 1;
start.hour = 9;
start.minute = 0;
start.month = 1;
start.year = 3100;
//Set default time zone
timezone=0;
timezone = 0;
//Start EQTimer
setEQTimeOfDay(start, time(0));
SetCurrentEQTimeOfDay(start, time(0));
}
EQTime::~EQTime()
@@ -67,10 +67,10 @@ EQTime::~EQTime()
//Input: Current Time (as a time_t), a pointer to the TimeOfDay_Struct that will be written to.
//Output: 0=Error, 1=Sucess
int EQTime::getEQTimeOfDay( time_t timeConvert, struct TimeOfDay_Struct *eqTimeOfDay )
int EQTime::GetCurrentEQTimeOfDay(time_t timeConvert, struct TimeOfDay_Struct *eqTimeOfDay)
{
/* check to see if we have a reference time to go by. */
if( eqTime.start_realtime == 0 )
if (eqTime.start_realtime == 0)
return 0;
unsigned long diff = timeConvert - eqTime.start_realtime;
@@ -83,7 +83,7 @@ int EQTime::getEQTimeOfDay( time_t timeConvert, struct TimeOfDay_Struct *eqTimeO
int32 ntz = timezone;
/* The minutes range from 0 - 59 */
diff += eqTime.start_eqtime.minute + (ntz%60);
diff += eqTime.start_eqtime.minute + (ntz % 60);
eqTimeOfDay->minute = diff % 60;
diff /= 60;
ntz /= 60;
@@ -97,24 +97,24 @@ int EQTime::getEQTimeOfDay( time_t timeConvert, struct TimeOfDay_Struct *eqTimeO
//
// Modify it so that it works from
// 0-23 for our calculations
diff += ( eqTime.start_eqtime.hour - 1) + (ntz%24);
eqTimeOfDay->hour = (diff%24) + 1;
diff += (eqTime.start_eqtime.hour - 1) + (ntz % 24);
eqTimeOfDay->hour = (diff % 24) + 1;
diff /= 24;
ntz /= 24;
// The days range from 1-28
// Modify it so that it works from
// 0-27 for our calculations
diff += ( eqTime.start_eqtime.day - 1 ) + (ntz%28);
eqTimeOfDay->day = (diff%28) + 1;
diff += (eqTime.start_eqtime.day - 1) + (ntz % 28);
eqTimeOfDay->day = (diff % 28) + 1;
diff /= 28;
ntz /= 28;
// The months range from 1-12
// Modify it so that it works from
// 0-11 for our calculations
diff += ( eqTime.start_eqtime.month - 1 ) + (ntz%12);
eqTimeOfDay->month = (diff%12) + 1;
diff += (eqTime.start_eqtime.month - 1) + (ntz % 12);
eqTimeOfDay->month = (diff % 12) + 1;
diff /= 12;
ntz /= 12;
@@ -124,12 +124,12 @@ int EQTime::getEQTimeOfDay( time_t timeConvert, struct TimeOfDay_Struct *eqTimeO
}
//setEQTimeOfDay
int EQTime::setEQTimeOfDay(TimeOfDay_Struct start_eq, time_t start_real)
int EQTime::SetCurrentEQTimeOfDay(TimeOfDay_Struct start_eq, time_t start_real)
{
if(start_real==0)
if (start_real == 0)
return 0;
eqTime.start_eqtime=start_eq;
eqTime.start_realtime=start_real;
eqTime.start_eqtime = start_eq;
eqTime.start_realtime = start_real;
return 1;
}
@@ -139,7 +139,7 @@ bool EQTime::saveFile(const char *filename)
{
std::ofstream of;
of.open(filename);
if(!of)
if (!of)
{
Log.Out(Logs::General, Logs::Error, "EQTime::saveFile failed: Unable to open file '%s'", filename);
return false;
@@ -200,24 +200,24 @@ bool EQTime::loadFile(const char *filename)
bool EQTime::IsTimeBefore(TimeOfDay_Struct *base, TimeOfDay_Struct *test) {
if(base->year > test->year)
if (base->year > test->year)
return(true);
if(base->year < test->year)
if (base->year < test->year)
return(false);
//same years
if(base->month > test->month)
if (base->month > test->month)
return(true);
if(base->month < test->month)
if (base->month < test->month)
return(false);
//same month
if(base->day > test->day)
if (base->day > test->day)
return(true);
if(base->day < test->day)
if (base->day < test->day)
return(false);
//same day
if(base->hour > test->hour)
if (base->hour > test->hour)
return(true);
if(base->hour < test->hour)
if (base->hour < test->hour)
return(false);
//same hour...
return(base->minute > test->minute);
@@ -230,7 +230,7 @@ void EQTime::AddMinutes(uint32 minutes, TimeOfDay_Struct *to) {
//minutes start at 0, everything else starts at 1
cur = to->minute;
cur += minutes;
if(cur < 60) {
if (cur < 60) {
to->minute = cur;
return;
}
@@ -238,29 +238,29 @@ void EQTime::AddMinutes(uint32 minutes, TimeOfDay_Struct *to) {
//carry hours
cur /= 60;
cur += to->hour;
if(cur <= 24) {
if (cur <= 24) {
to->hour = cur;
return;
}
to->hour = ((cur-1) % 24) + 1;
to->hour = ((cur - 1) % 24) + 1;
//carry days
cur = (cur-1) / 24;
cur = (cur - 1) / 24;
cur += to->day;
if(cur <= 28) {
if (cur <= 28) {
to->day = cur;
return;
}
to->day = ((cur-1) % 28) + 1;
to->day = ((cur - 1) % 28) + 1;
//carry months
cur = (cur-1) / 28;
cur = (cur - 1) / 28;
cur += to->month;
if(cur <= 12) {
if (cur <= 12) {
to->month = cur;
return;
}
to->month = ((cur-1) % 12) + 1;
to->month = ((cur - 1) % 12) + 1;
//carry years
to->year += (cur-1) / 12;
to->year += (cur - 1) / 12;
}
void EQTime::ToString(TimeOfDay_Struct *t, std::string &str) {
@@ -269,5 +269,4 @@ void EQTime::ToString(TimeOfDay_Struct *t, std::string &str) {
t->month, t->day, t->year, t->hour, t->minute);
buf[127] = '\0';
str = buf;
}
}
+3 -3
View File
@@ -21,8 +21,8 @@ public:
~EQTime();
//Get functions
int getEQTimeOfDay( TimeOfDay_Struct *eqTimeOfDay ) { return(getEQTimeOfDay(time(nullptr), eqTimeOfDay)); }
int getEQTimeOfDay( time_t timeConvert, TimeOfDay_Struct *eqTimeOfDay );
int GetCurrentEQTimeOfDay( TimeOfDay_Struct *eqTimeOfDay ) { return(GetCurrentEQTimeOfDay(time(nullptr), eqTimeOfDay)); }
int GetCurrentEQTimeOfDay( time_t timeConvert, TimeOfDay_Struct *eqTimeOfDay );
TimeOfDay_Struct getStartEQTime() { return eqTime.start_eqtime; }
time_t getStartRealTime() { return eqTime.start_realtime; }
uint32 getEQTimeZone() { return timezone; }
@@ -30,7 +30,7 @@ public:
uint32 getEQTimeZoneMin() { return timezone%60; }
//Set functions
int setEQTimeOfDay(TimeOfDay_Struct start_eq, time_t start_real);
int SetCurrentEQTimeOfDay(TimeOfDay_Struct start_eq, time_t start_real);
void setEQTimeZone(int32 in_timezone) { timezone=in_timezone; }
//Time math/logic functions
-1
View File
@@ -26,7 +26,6 @@ void InitExtendedProfile(ExtendedProfile_Struct *p) {
}
bool SetExtendedProfile(ExtendedProfile_Struct *to, char *old, unsigned int len) {
_eqp
if(len == 0 || old == nullptr) {
//handle old chars without an extended profile...
InitExtendedProfile(to);
-4
View File
@@ -21,7 +21,6 @@
const char *FactionValueToString(FACTION_VALUE fv)
{
_eqp
switch (fv) {
case FACTION_ALLY:
return ("Ally");
@@ -56,7 +55,6 @@ const char *FactionValueToString(FACTION_VALUE fv)
//o--------------------------------------------------------------
FACTION_VALUE CalculateFaction(FactionMods* fm, int32 tmpCharacter_value)
{
_eqp
int32 character_value = tmpCharacter_value;
if (fm) {
character_value += fm->base + fm->class_mod + fm->race_mod + fm->deity_mod;
@@ -94,7 +92,6 @@ FACTION_VALUE CalculateFaction(FactionMods* fm, int32 tmpCharacter_value)
// this function should check if some races have more than one race define
bool IsOfEqualRace(int r1, int r2)
{
_eqp
if (r1 == r2) {
return true;
}
@@ -116,7 +113,6 @@ bool IsOfEqualRace(int r1, int r2)
// trolls endure ogres, dark elves, ...
bool IsOfIndiffRace(int r1, int r2)
{
_eqp
if (r1 == r2) {
return true;
}
+88
View File
@@ -0,0 +1,88 @@
#include "global_define.h"
#include "types.h"
#include "clientversions.h"
#include "file_verify.h"
#include "crc32.h"
#include <stdio.h>
#pragma pack(1)
struct VerifyFileStruct
{
uint32 crc;
uint32 file_size;
uint32 offset[256];
uint32 data[256];
};
#pragma pack()
EQEmu::FileVerify::FileVerify() {
buffer = nullptr;
size = 0;
}
EQEmu::FileVerify::~FileVerify() {
safe_delete_array(buffer);
}
bool EQEmu::FileVerify::Load(const char *file_name) {
safe_delete_array(buffer);
size = 0;
FILE *f = fopen(file_name, "rb");
if(!f) {
buffer = nullptr;
size = 0;
return false;
}
fseek(f, 0U, SEEK_END);
size = ftell(f);
rewind(f);
buffer = new char[size];
auto result = fread(buffer, 1, size, f);
fclose(f);
if(result != size) {
safe_delete_array(buffer);
size = 0;
}
return true;
}
bool EQEmu::FileVerify::Verify(const char *data, uint32 size, ClientVersion version) {
if(!buffer) {
return true;
}
if(size != sizeof(VerifyFileStruct)) {
return false;
}
VerifyFileStruct *vs = (VerifyFileStruct*)data;
if(this->size != vs->file_size) {
return false;
}
uint32 crc = CRC32::GenerateNoFlip((uchar*)buffer, this->size);
if(vs->crc != crc) {
return false;
}
for(int i = 0; i < 256; ++i) {
uint32 offset = vs->offset[i] * 4;
if((offset - 4) > this->size) {
return false;
}
uint32 check = *(uint32*)(buffer + offset);
if(check != vs->data[i]) {
return false;
}
}
return true;
}
+21
View File
@@ -0,0 +1,21 @@
#ifndef EQEMU_COMMON_FILE_VERIFY_H
#define EQEMU_COMMON_FILE_VERIFY_H
namespace EQEmu
{
class FileVerify
{
public:
FileVerify();
~FileVerify();
bool Load(const char *file_name);
bool Verify(const char *data, uint32 size, ClientVersion version);
private:
char *buffer;
uint32 size;
};
}
#endif
+87
View File
@@ -0,0 +1,87 @@
#include "global_define.h"
#include "types.h"
#include "clientversions.h"
#include "eq_packet.h"
#include "file_verify_manager.h"
#include "string_util.h"
#include <memory>
struct EQEmu::FileVerifyManager::impl {
std::unique_ptr<FileVerify> spell_data;
std::unique_ptr<FileVerify> skill_data;
std::unique_ptr<FileVerify> base_data;
std::unique_ptr<FileVerify> eqgames[(int)ClientVersion::MaxClientVersions];
};
EQEmu::FileVerifyManager::FileVerifyManager() {
impl_ = new impl;
impl_->spell_data.reset(new FileVerify());
impl_->spell_data->Load("verify/spells_us.txt");
impl_->skill_data.reset(new FileVerify());
impl_->skill_data->Load("verify/SkillCaps.txt");
impl_->base_data.reset(new FileVerify());
impl_->base_data->Load("verify/BaseData.txt");
for(int i = 0; i < (int)ClientVersion::MaxClientVersions; ++i) {
impl_->eqgames[i].reset(nullptr);
}
}
EQEmu::FileVerifyManager::~FileVerifyManager() {
delete impl_;
}
bool EQEmu::FileVerifyManager::VerifySpellFile(const EQApplicationPacket *app, ClientVersion version) {
if(!impl_->spell_data) {
impl_->spell_data.reset(new FileVerify());
if(!impl_->spell_data->Load("verify/spells_us.txt")) {
return true;
}
}
return impl_->spell_data->Verify((char*)app->pBuffer, app->size, version);
}
bool EQEmu::FileVerifyManager::VerifySkillFile(const EQApplicationPacket *app, ClientVersion version) {
if(!impl_->skill_data) {
impl_->skill_data.reset(new FileVerify());
if(!impl_->skill_data->Load("verify/SkillCaps.txt")) {
return true;
}
}
return impl_->skill_data->Verify((char*)app->pBuffer, app->size, version);
}
bool EQEmu::FileVerifyManager::VerifyBaseDataFile(const EQApplicationPacket *app, ClientVersion version) {
if(!impl_->base_data) {
impl_->base_data.reset(new FileVerify());
if(!impl_->base_data->Load("verify/BaseData.txt")) {
return true;
}
}
return impl_->base_data->Verify((char*)app->pBuffer, app->size, version);
}
bool EQEmu::FileVerifyManager::VerifyEQGame(const EQApplicationPacket *app, ClientVersion version) {
int v = (int)version;
if(v >= (int)ClientVersion::MaxClientVersions) {
return true;
}
if(!impl_->eqgames[v]) {
impl_->eqgames[v].reset(new FileVerify());
if(!impl_->eqgames[v]->Load(StringFormat("verify/%s/eqgame.exe", ClientVersionName(version)).c_str())) {
return true;
}
}
return impl_->eqgames[v]->Verify((char*)app->pBuffer, app->size, version);
}
+33
View File
@@ -0,0 +1,33 @@
#ifndef EQEMU_COMMON_FILE_VERIFY_MANAGER_H
#define EQEMU_COMMON_FILE_VERIFY_MANAGER_H
#include "file_verify.h"
namespace EQEmu
{
class FileVerifyManager
{
public:
~FileVerifyManager();
static FileVerifyManager& Get()
{
static FileVerifyManager instance;
return instance;
}
bool VerifySpellFile(const EQApplicationPacket *app, ClientVersion version);
bool VerifySkillFile(const EQApplicationPacket *app, ClientVersion version);
bool VerifyBaseDataFile(const EQApplicationPacket *app, ClientVersion version);
bool VerifyEQGame(const EQApplicationPacket *app, ClientVersion version);
private:
FileVerifyManager();
FileVerifyManager(FileVerifyManager const&);
void operator=(FileVerifyManager const&);
struct impl;
impl *impl_;
};
}
#endif
+3 -57
View File
@@ -39,8 +39,10 @@ BaseGuildManager::~BaseGuildManager() {
ClearGuilds();
}
bool BaseGuildManager::LoadGuilds() {
_eqp
ClearGuilds();
if(m_db == nullptr) {
@@ -102,7 +104,6 @@ bool BaseGuildManager::LoadGuilds() {
}
bool BaseGuildManager::RefreshGuild(uint32 guild_id) {
_eqp
if(m_db == nullptr) {
Log.Out(Logs::Detail, Logs::Guilds, "Requested to refresh guild %d when we have no database object.", guild_id);
return(false);
@@ -168,7 +169,6 @@ bool BaseGuildManager::RefreshGuild(uint32 guild_id) {
BaseGuildManager::GuildInfo *BaseGuildManager::_CreateGuild(uint32 guild_id, const char *guild_name, uint32 leader_char_id, uint8 minstatus, const char *guild_motd, const char *motd_setter, const char *Channel, const char *URL)
{
_eqp
std::map<uint32, GuildInfo *>::iterator res;
//remove any old entry.
@@ -213,7 +213,6 @@ BaseGuildManager::GuildInfo *BaseGuildManager::_CreateGuild(uint32 guild_id, con
}
bool BaseGuildManager::_StoreGuildDB(uint32 guild_id) {
_eqp
if(m_db == nullptr) {
Log.Out(Logs::Detail, Logs::Guilds, "Requested to store guild %d when we have no database object.", guild_id);
return(false);
@@ -296,7 +295,6 @@ bool BaseGuildManager::_StoreGuildDB(uint32 guild_id) {
}
uint32 BaseGuildManager::_GetFreeGuildID() {
_eqp
if(m_db == nullptr) {
Log.Out(Logs::Detail, Logs::Guilds, "Requested find a free guild ID when we have no database object.");
return(GUILD_NONE);
@@ -344,7 +342,6 @@ uint32 BaseGuildManager::_GetFreeGuildID() {
uint32 BaseGuildManager::CreateGuild(const char* name, uint32 leader_char_id) {
_eqp
uint32 gid = DBCreateGuild(name, leader_char_id);
if(gid == GUILD_NONE)
return(GUILD_NONE);
@@ -356,7 +353,6 @@ uint32 BaseGuildManager::CreateGuild(const char* name, uint32 leader_char_id) {
}
bool BaseGuildManager::DeleteGuild(uint32 guild_id) {
_eqp
if(!DBDeleteGuild(guild_id))
return(false);
@@ -366,7 +362,6 @@ bool BaseGuildManager::DeleteGuild(uint32 guild_id) {
}
bool BaseGuildManager::RenameGuild(uint32 guild_id, const char* name) {
_eqp
if(!DBRenameGuild(guild_id, name))
return(false);
@@ -376,7 +371,6 @@ bool BaseGuildManager::RenameGuild(uint32 guild_id, const char* name) {
}
bool BaseGuildManager::SetGuildLeader(uint32 guild_id, uint32 leader_char_id) {
_eqp
//get old leader first.
std::map<uint32, GuildInfo *>::const_iterator res;
res = m_guilds.find(guild_id);
@@ -396,7 +390,6 @@ bool BaseGuildManager::SetGuildLeader(uint32 guild_id, uint32 leader_char_id) {
}
bool BaseGuildManager::SetGuildMOTD(uint32 guild_id, const char* motd, const char *setter) {
_eqp
if(!DBSetGuildMOTD(guild_id, motd, setter))
return(false);
@@ -407,7 +400,6 @@ bool BaseGuildManager::SetGuildMOTD(uint32 guild_id, const char* motd, const cha
bool BaseGuildManager::SetGuildURL(uint32 GuildID, const char* URL)
{
_eqp
if(!DBSetGuildURL(GuildID, URL))
return(false);
@@ -418,7 +410,6 @@ bool BaseGuildManager::SetGuildURL(uint32 GuildID, const char* URL)
bool BaseGuildManager::SetGuildChannel(uint32 GuildID, const char* Channel)
{
_eqp
if(!DBSetGuildChannel(GuildID, Channel))
return(false);
@@ -428,7 +419,6 @@ bool BaseGuildManager::SetGuildChannel(uint32 GuildID, const char* Channel)
}
bool BaseGuildManager::SetGuild(uint32 charid, uint32 guild_id, uint8 rank) {
_eqp
if(rank > GUILD_MAX_RANK && guild_id != GUILD_NONE)
return(false);
@@ -449,7 +439,6 @@ bool BaseGuildManager::SetGuild(uint32 charid, uint32 guild_id, uint8 rank) {
//changes rank, but not guild.
bool BaseGuildManager::SetGuildRank(uint32 charid, uint8 rank) {
_eqp
if(rank > GUILD_MAX_RANK)
return(false);
@@ -463,7 +452,6 @@ bool BaseGuildManager::SetGuildRank(uint32 charid, uint8 rank) {
bool BaseGuildManager::SetBankerFlag(uint32 charid, bool is_banker) {
_eqp
if(!DBSetBankerFlag(charid, is_banker))
return(false);
@@ -473,14 +461,12 @@ bool BaseGuildManager::SetBankerFlag(uint32 charid, bool is_banker) {
}
bool BaseGuildManager::ForceRankUpdate(uint32 charid) {
_eqp
SendRankUpdate(charid);
return(true);
}
bool BaseGuildManager::SetAltFlag(uint32 charid, bool is_alt)
{
_eqp
if(!DBSetAltFlag(charid, is_alt))
return(false);
@@ -490,7 +476,6 @@ bool BaseGuildManager::SetAltFlag(uint32 charid, bool is_alt)
}
bool BaseGuildManager::SetTributeFlag(uint32 charid, bool enabled) {
_eqp
if(!DBSetTributeFlag(charid, enabled))
return(false);
@@ -500,7 +485,6 @@ bool BaseGuildManager::SetTributeFlag(uint32 charid, bool enabled) {
}
bool BaseGuildManager::SetPublicNote(uint32 charid, const char *note) {
_eqp
if(!DBSetPublicNote(charid, note))
return(false);
@@ -510,7 +494,6 @@ bool BaseGuildManager::SetPublicNote(uint32 charid, const char *note) {
}
uint32 BaseGuildManager::DBCreateGuild(const char* name, uint32 leader) {
_eqp
//first try to find a free ID.
uint32 new_id = _GetFreeGuildID();
if(new_id == GUILD_NONE)
@@ -532,7 +515,6 @@ uint32 BaseGuildManager::DBCreateGuild(const char* name, uint32 leader) {
}
bool BaseGuildManager::DBDeleteGuild(uint32 guild_id) {
_eqp
//remove the local entry
std::map<uint32, GuildInfo *>::iterator res;
@@ -569,7 +551,6 @@ bool BaseGuildManager::DBDeleteGuild(uint32 guild_id) {
}
bool BaseGuildManager::DBRenameGuild(uint32 guild_id, const char* name) {
_eqp
if(m_db == nullptr) {
Log.Out(Logs::Detail, Logs::Guilds, "Requested to rename guild %d when we have no database object.", guild_id);
return false;
@@ -606,7 +587,6 @@ bool BaseGuildManager::DBRenameGuild(uint32 guild_id, const char* name) {
}
bool BaseGuildManager::DBSetGuildLeader(uint32 guild_id, uint32 leader) {
_eqp
if(m_db == nullptr) {
Log.Out(Logs::Detail, Logs::Guilds, "Requested to set the leader for guild %d when we have no database object.", guild_id);
return false;
@@ -642,7 +622,6 @@ bool BaseGuildManager::DBSetGuildLeader(uint32 guild_id, uint32 leader) {
}
bool BaseGuildManager::DBSetGuildMOTD(uint32 guild_id, const char* motd, const char *setter) {
_eqp
if(m_db == nullptr) {
Log.Out(Logs::Detail, Logs::Guilds, "Requested to set the MOTD for guild %d when we have no database object.", guild_id);
return(false);
@@ -685,7 +664,6 @@ bool BaseGuildManager::DBSetGuildMOTD(uint32 guild_id, const char* motd, const c
bool BaseGuildManager::DBSetGuildURL(uint32 GuildID, const char* URL)
{
_eqp
if(m_db == nullptr)
return false;
@@ -719,7 +697,6 @@ bool BaseGuildManager::DBSetGuildURL(uint32 GuildID, const char* URL)
bool BaseGuildManager::DBSetGuildChannel(uint32 GuildID, const char* Channel)
{
_eqp
if(m_db == nullptr)
return(false);
@@ -753,7 +730,6 @@ bool BaseGuildManager::DBSetGuildChannel(uint32 GuildID, const char* Channel)
}
bool BaseGuildManager::DBSetGuild(uint32 charid, uint32 guild_id, uint8 rank) {
_eqp
if(m_db == nullptr) {
Log.Out(Logs::Detail, Logs::Guilds, "Requested to set char to guild %d when we have no database object.", guild_id);
return(false);
@@ -782,13 +758,11 @@ bool BaseGuildManager::DBSetGuild(uint32 charid, uint32 guild_id, uint8 rank) {
}
bool BaseGuildManager::DBSetGuildRank(uint32 charid, uint8 rank) {
_eqp
std::string query = StringFormat("UPDATE guild_members SET rank=%d WHERE char_id=%d", rank, charid);
return(QueryWithLogging(query, "setting a guild member's rank"));
}
bool BaseGuildManager::DBSetBankerFlag(uint32 charid, bool is_banker) {
_eqp
std::string query = StringFormat("UPDATE guild_members SET banker=%d WHERE char_id=%d",
is_banker? 1: 0, charid);
return(QueryWithLogging(query, "setting a guild member's banker flag"));
@@ -796,7 +770,6 @@ bool BaseGuildManager::DBSetBankerFlag(uint32 charid, bool is_banker) {
bool BaseGuildManager::GetBankerFlag(uint32 CharID)
{
_eqp
if(!m_db)
return false;
@@ -819,7 +792,6 @@ bool BaseGuildManager::GetBankerFlag(uint32 CharID)
bool BaseGuildManager::DBSetAltFlag(uint32 charid, bool is_alt)
{
_eqp
std::string query = StringFormat("UPDATE guild_members SET alt=%d WHERE char_id=%d",
is_alt ? 1: 0, charid);
@@ -828,7 +800,6 @@ bool BaseGuildManager::DBSetAltFlag(uint32 charid, bool is_alt)
bool BaseGuildManager::GetAltFlag(uint32 CharID)
{
_eqp
if(!m_db)
return false;
@@ -850,14 +821,12 @@ bool BaseGuildManager::GetAltFlag(uint32 CharID)
}
bool BaseGuildManager::DBSetTributeFlag(uint32 charid, bool enabled) {
_eqp
std::string query = StringFormat("UPDATE guild_members SET tribute_enable=%d WHERE char_id=%d",
enabled ? 1: 0, charid);
return(QueryWithLogging(query, "setting a guild member's tribute flag"));
}
bool BaseGuildManager::DBSetPublicNote(uint32 charid, const char* note) {
_eqp
if(m_db == nullptr)
return(false);
@@ -882,7 +851,6 @@ bool BaseGuildManager::DBSetPublicNote(uint32 charid, const char* note) {
}
bool BaseGuildManager::QueryWithLogging(std::string query, const char *errmsg) {
_eqp
if(m_db == nullptr)
return(false);
@@ -911,7 +879,6 @@ bool BaseGuildManager::QueryWithLogging(std::string query, const char *errmsg) {
" FROM `character_data` AS c LEFT JOIN guild_members AS g ON c.id=g.char_id "
#endif
static void ProcessGuildMember(MySQLRequestRow row, CharGuildInfo &into) {
_eqp
//fields from `characer_`
into.char_id = atoi(row[0]);
into.char_name = row[1];
@@ -939,7 +906,6 @@ static void ProcessGuildMember(MySQLRequestRow row, CharGuildInfo &into) {
bool BaseGuildManager::GetEntireGuild(uint32 guild_id, std::vector<CharGuildInfo *> &members) {
_eqp
members.clear();
if(m_db == nullptr)
@@ -964,7 +930,6 @@ bool BaseGuildManager::GetEntireGuild(uint32 guild_id, std::vector<CharGuildInfo
}
bool BaseGuildManager::GetCharInfo(const char *char_name, CharGuildInfo &into) {
_eqp
if(m_db == nullptr) {
Log.Out(Logs::Detail, Logs::Guilds, "Requested char info on %s when we have no database object.", char_name);
return(false);
@@ -996,7 +961,6 @@ bool BaseGuildManager::GetCharInfo(const char *char_name, CharGuildInfo &into) {
}
bool BaseGuildManager::GetCharInfo(uint32 char_id, CharGuildInfo &into) {
_eqp
if(m_db == nullptr) {
Log.Out(Logs::Detail, Logs::Guilds, "Requested char info on %d when we have no database object.", char_id);
return false;
@@ -1027,7 +991,6 @@ bool BaseGuildManager::GetCharInfo(uint32 char_id, CharGuildInfo &into) {
//returns ownership of the buffer.
uint8 *BaseGuildManager::MakeGuildList(const char *head_name, uint32 &length) const {
_eqp
//dynamic structs will make this a lot less painful.
length = sizeof(GuildsList_Struct);
@@ -1055,7 +1018,6 @@ uint8 *BaseGuildManager::MakeGuildList(const char *head_name, uint32 &length) co
}
const char *BaseGuildManager::GetRankName(uint32 guild_id, uint8 rank) const {
_eqp
if(rank > GUILD_MAX_RANK)
return("Invalid Rank");
std::map<uint32, GuildInfo *>::const_iterator res;
@@ -1066,7 +1028,6 @@ const char *BaseGuildManager::GetRankName(uint32 guild_id, uint8 rank) const {
}
const char *BaseGuildManager::GetGuildName(uint32 guild_id) const {
_eqp
if(guild_id == GUILD_NONE)
return("");
std::map<uint32, GuildInfo *>::const_iterator res;
@@ -1077,7 +1038,6 @@ const char *BaseGuildManager::GetGuildName(uint32 guild_id) const {
}
bool BaseGuildManager::GetGuildNameByID(uint32 guild_id, std::string &into) const {
_eqp
std::map<uint32, GuildInfo *>::const_iterator res;
res = m_guilds.find(guild_id);
if(res == m_guilds.end())
@@ -1088,7 +1048,6 @@ bool BaseGuildManager::GetGuildNameByID(uint32 guild_id, std::string &into) cons
uint32 BaseGuildManager::GetGuildIDByName(const char *GuildName)
{
_eqp
std::map<uint32, GuildInfo *>::iterator Iterator;
for(Iterator = m_guilds.begin(); Iterator != m_guilds.end(); ++Iterator)
@@ -1101,7 +1060,6 @@ uint32 BaseGuildManager::GetGuildIDByName(const char *GuildName)
}
bool BaseGuildManager::GetGuildMOTD(uint32 guild_id, char *motd_buffer, char *setter_buffer) const {
_eqp
std::map<uint32, GuildInfo *>::const_iterator res;
res = m_guilds.find(guild_id);
if(res == m_guilds.end())
@@ -1113,7 +1071,6 @@ bool BaseGuildManager::GetGuildMOTD(uint32 guild_id, char *motd_buffer, char *se
bool BaseGuildManager::GetGuildURL(uint32 GuildID, char *URLBuffer) const
{
_eqp
std::map<uint32, GuildInfo *>::const_iterator res;
res = m_guilds.find(GuildID);
if(res == m_guilds.end())
@@ -1125,7 +1082,6 @@ bool BaseGuildManager::GetGuildURL(uint32 GuildID, char *URLBuffer) const
bool BaseGuildManager::GetGuildChannel(uint32 GuildID, char *ChannelBuffer) const
{
_eqp
std::map<uint32, GuildInfo *>::const_iterator res;
res = m_guilds.find(GuildID);
if(res == m_guilds.end())
@@ -1135,14 +1091,12 @@ bool BaseGuildManager::GetGuildChannel(uint32 GuildID, char *ChannelBuffer) cons
}
bool BaseGuildManager::GuildExists(uint32 guild_id) const {
_eqp
if(guild_id == GUILD_NONE)
return(false);
return(m_guilds.find(guild_id) != m_guilds.end());
}
bool BaseGuildManager::IsGuildLeader(uint32 guild_id, uint32 char_id) const {
_eqp
if(guild_id == GUILD_NONE) {
Log.Out(Logs::Detail, Logs::Guilds, "Check leader for char %d: not a guild.", char_id);
return(false);
@@ -1158,7 +1112,6 @@ bool BaseGuildManager::IsGuildLeader(uint32 guild_id, uint32 char_id) const {
}
uint32 BaseGuildManager::FindGuildByLeader(uint32 leader) const {
_eqp
std::map<uint32, GuildInfo *>::const_iterator cur, end;
cur = m_guilds.begin();
end = m_guilds.end();
@@ -1171,7 +1124,6 @@ uint32 BaseGuildManager::FindGuildByLeader(uint32 leader) const {
//returns the rank to be sent to the client for display purposes, given their eqemu rank.
uint8 BaseGuildManager::GetDisplayedRank(uint32 guild_id, uint8 rank, uint32 char_id) const {
_eqp
std::map<uint32, GuildInfo *>::const_iterator res;
res = m_guilds.find(guild_id);
if(res == m_guilds.end())
@@ -1184,7 +1136,6 @@ uint8 BaseGuildManager::GetDisplayedRank(uint32 guild_id, uint8 rank, uint32 cha
}
bool BaseGuildManager::CheckGMStatus(uint32 guild_id, uint8 status) const {
_eqp
if(status >= 250) {
Log.Out(Logs::Detail, Logs::Guilds, "Check permission on guild %d with user status %d > 250, granted.", guild_id, status);
return(true); //250+ as allowed anything
@@ -1206,7 +1157,6 @@ bool BaseGuildManager::CheckGMStatus(uint32 guild_id, uint8 status) const {
}
bool BaseGuildManager::CheckPermission(uint32 guild_id, uint8 rank, GuildAction act) const {
_eqp
if(rank > GUILD_MAX_RANK) {
Log.Out(Logs::Detail, Logs::Guilds, "Check permission on guild %d and rank %d for action %s (%d): Invalid rank, denied.",
guild_id, rank, GuildActionNames[act], act);
@@ -1232,7 +1182,6 @@ bool BaseGuildManager::CheckPermission(uint32 guild_id, uint8 rank, GuildAction
}
bool BaseGuildManager::LocalDeleteGuild(uint32 guild_id) {
_eqp
std::map<uint32, GuildInfo *>::iterator res;
res = m_guilds.find(guild_id);
if(res == m_guilds.end())
@@ -1252,21 +1201,18 @@ void BaseGuildManager::ClearGuilds() {
}
BaseGuildManager::RankInfo::RankInfo() {
_eqp
uint8 r;
for(r = 0; r < _MaxGuildAction; r++)
permissions[r] = false;
}
BaseGuildManager::GuildInfo::GuildInfo() {
_eqp
leader_char_id = 0;
minstatus = 0;
}
uint32 BaseGuildManager::DoesAccountContainAGuildLeader(uint32 AccountID)
{
_eqp
std::string query = StringFormat("SELECT guild_id FROM guild_members WHERE char_id IN "
"(SELECT id FROM `character_data` WHERE account_id = %i) AND rank = 2",
AccountID);
+85 -13
View File
@@ -660,7 +660,7 @@ int16 Inventory::FindFreeSlotForTradeItem(const ItemInst* inst) {
// Do not arbitrarily use this function..it is designed for use with Client::ResetTrade() and Client::FinishTrade().
// If you have a need, use it..but, understand it is not a compatible replacement for Inventory::FindFreeSlot().
//
// I'll probably implement a bitmask in the new inventory system to avoid having to adjust stack bias -U
// I'll probably implement a bitmask in the new inventory system to avoid having to adjust stack bias
if (!inst || !inst->GetID())
return INVALID_INDEX;
@@ -993,34 +993,43 @@ int Inventory::GetSlotByItemInst(ItemInst *inst) {
return INVALID_INDEX;
}
uint8 Inventory::FindHighestLightValue()
uint8 Inventory::FindBrightestLightType()
{
uint8 light_value = NOT_USED;
uint8 brightest_light_type = 0;
// NOTE: The client does not recognize augment light sources, applied or otherwise, and should not be parsed
for (auto iter = m_worn.begin(); iter != m_worn.end(); ++iter) {
if ((iter->first < EmuConstants::EQUIPMENT_BEGIN || iter->first > EmuConstants::EQUIPMENT_END) && iter->first != MainPowerSource) { continue; }
if (iter->first == MainAmmo) { continue; }
auto inst = iter->second;
if (inst == nullptr) { continue; }
auto item = inst->GetItem();
if (item == nullptr) { continue; }
if (item->Light & 0xF0) { continue; }
if (item->Light > light_value) { light_value = item->Light; }
if (LightProfile_Struct::IsLevelGreater(item->Light, brightest_light_type))
brightest_light_type = item->Light;
}
uint8 general_light_type = 0;
for (auto iter = m_inv.begin(); iter != m_inv.end(); ++iter) {
if (iter->first < EmuConstants::GENERAL_BEGIN || iter->first > EmuConstants::GENERAL_END) { continue; }
auto inst = iter->second;
if (inst == nullptr) { continue; }
auto item = inst->GetItem();
if (item == nullptr) { continue; }
// 'Gloomingdeep lantern' is ItemTypeArmor in the database..there may be others instances and/or types that need to be handled
if (item->ItemType != ItemTypeMisc && item->ItemType != ItemTypeLight && item->ItemType != ItemTypeArmor) { continue; }
if (item->Light & 0xF0) { continue; }
if (item->Light > light_value) { light_value = item->Light; }
if (item->ItemClass != ItemClassCommon) { continue; }
if (item->Light < 9 || item->Light > 13) { continue; }
if (LightProfile_Struct::TypeToLevel(item->Light))
general_light_type = item->Light;
}
return light_value;
if (LightProfile_Struct::IsLevelGreater(general_light_type, brightest_light_type))
brightest_light_type = general_light_type;
return brightest_light_type;
}
void Inventory::dumpEntireInventory() {
@@ -1232,7 +1241,7 @@ int16 Inventory::_HasItem(ItemInstQueue& iqueue, uint32 item_id, uint8 quantity)
// found, it is presented as being available on the cursor. In cases of a parity check, this
// is sufficient. However, in cases where referential criteria is considered, this can lead
// to unintended results. Funtionality should be observed when referencing the return value
// of this query -U
// of this query
uint8 quantity_found = 0;
@@ -2148,7 +2157,7 @@ ItemInst* ItemInst::Clone() const
}
bool ItemInst::IsSlotAllowed(int16 slot_id) const {
// 'SupportsContainers' and 'slot_id > 21' previously saw the reassigned PowerSource slot (9999 to 22) as valid -U
// 'SupportsContainers' and 'slot_id > 21' previously saw the reassigned PowerSource slot (9999 to 22) as valid
if (!m_item) { return false; }
else if (Inventory::SupportsContainers(slot_id)) { return true; }
else if (m_item->Slots & (1 << slot_id)) { return true; }
@@ -2361,3 +2370,66 @@ bool Item_Struct::IsEquipable(uint16 Race, uint16 Class_) const
return (IsRace && IsClass);
}
//
// struct LightProfile_Struct
//
uint8 LightProfile_Struct::TypeToLevel(uint8 lightType)
{
switch (lightType) {
case lightTypeGlobeOfStars:
return lightLevelBrilliant; // 10
case lightTypeFlamelessLantern:
case lightTypeGreaterLightstone:
return lightLevelLargeMagic; // 9
case lightTypeLargeLantern:
return lightLevelLargeLantern; // 8
case lightTypeSteinOfMoggok:
case lightTypeLightstone:
return lightLevelMagicLantern; // 7
case lightTypeSmallLantern:
return lightLevelSmallLantern; // 6
case lightTypeColdlight:
case lightTypeUnknown2:
return lightLevelBlueLight; // 5
case lightTypeFireBeetleEye:
case lightTypeUnknown1:
return lightLevelRedLight; // 4
case lightTypeTinyGlowingSkull:
case lightTypeLightGlobe:
return lightLevelSmallMagic; // 3
case lightTypeTorch:
return lightLevelTorch; // 2
case lightLevelCandle:
return lightLevelCandle; // 1
default:
return lightLevelUnlit; // 0
}
}
bool LightProfile_Struct::IsLevelGreater(uint8 leftType, uint8 rightType)
{
static const uint8 light_levels[LIGHT_TYPES_COUNT] = {
lightLevelUnlit, /* lightTypeNone */
lightLevelCandle, /* lightTypeCandle */
lightLevelTorch, /* lightTypeTorch */
lightLevelSmallMagic, /* lightTypeTinyGlowingSkull */
lightLevelSmallLantern, /* lightTypeSmallLantern */
lightLevelMagicLantern, /* lightTypeSteinOfMoggok */
lightLevelLargeLantern, /* lightTypeLargeLantern */
lightLevelLargeMagic, /* lightTypeFlamelessLantern */
lightLevelBrilliant, /* lightTypeGlobeOfStars */
lightLevelSmallMagic, /* lightTypeLightGlobe */
lightLevelMagicLantern, /* lightTypeLightstone */
lightLevelLargeMagic, /* lightTypeGreaterLightstone */
lightLevelRedLight, /* lightTypeFireBeetleEye */
lightLevelBlueLight, /* lightTypeColdlight */
lightLevelRedLight, /* lightTypeUnknown1 */
lightLevelBlueLight /* lightTypeUnknown2 */
};
if (leftType >= LIGHT_TYPES_COUNT) { leftType = lightTypeNone; }
if (rightType >= LIGHT_TYPES_COUNT) { rightType = lightTypeNone; }
return (light_levels[leftType] > light_levels[rightType]);
}
+40 -1
View File
@@ -204,7 +204,7 @@ public:
int GetSlotByItemInst(ItemInst *inst);
uint8 FindHighestLightValue();
uint8 FindBrightestLightType();
void dumpEntireInventory();
void dumpWornItems();
@@ -472,4 +472,43 @@ public:
~EvolveInfo();
};
struct LightProfile_Struct
{
/*
Current criteria (light types):
Equipment: { 0 .. 15 }
General: { 9 .. 13 }
Notes:
- Initial character load and item movement updates use different light source update behaviors
-- Server procedure matches the item movement behavior since most updates occur post-character load
- MainAmmo is not considered when determining light sources
- No 'Sub' or 'Aug' items are recognized as light sources
- Light types '< 9' and '> 13' are not considered for general (carried) light sources
- If values > 0x0F are valid, then assignment limiters will need to be removed
- MainCursor 'appears' to be a valid light source update slot..but, have not experienced updates during debug sessions
- All clients have a bug regarding stackable items (light and sound updates are not processed when picking up an item)
-- The timer-based update cancels out the invalid light source
*/
static uint8 TypeToLevel(uint8 lightType);
static bool IsLevelGreater(uint8 leftType, uint8 rightType);
// Light types (classifications)
struct {
uint8 Innate; // Defined by db field `npc_types`.`light` - where appropriate
uint8 Equipment; // Item_Struct::light value of worn/carried equipment
uint8 Spell; // Set value of any light-producing spell (can be modded to mimic equip_light behavior)
uint8 Active; // Highest value of all light sources
} Type;
// Light levels (intensities) - used to determine which light source should be active
struct {
uint8 Innate;
uint8 Equipment;
uint8 Spell;
uint8 Active;
} Level;
};
#endif // #define __ITEM_H
+1 -1
View File
@@ -185,7 +185,7 @@ struct Item_Struct {
uint32 AugType;
uint8 AugSlotType[EmuConstants::ITEM_COMMON_SIZE]; // RoF: Augment Slot 1-6 Type
uint8 AugSlotVisible[EmuConstants::ITEM_COMMON_SIZE]; // RoF: Augment Slot 1-6 Visible
uint8 AugSlotUnk2[EmuConstants::ITEM_COMMON_SIZE]; // RoF: Augment Slot 1-6 Unknown
uint8 AugSlotUnk2[EmuConstants::ITEM_COMMON_SIZE]; // RoF: Augment Slot 1-6 Unknown Most likely Powersource related
uint32 LDoNTheme;
uint32 LDoNPrice;
uint32 LDoNSold;
+64 -34
View File
@@ -24,6 +24,36 @@
std::map<int,std::string> DBFieldNames;
#ifndef WIN32
#if defined(FREEBSD) || defined(__CYGWIN__)
int print_stacktrace()
{
printf("Insert stack trace here...\n");
return(0);
}
#else //!WIN32 && !FREEBSD == linux
#include <execinfo.h>
int print_stacktrace()
{
void *ba[20];
int n = backtrace (ba, 20);
if (n != 0)
{
char **names = backtrace_symbols (ba, n);
if (names != nullptr)
{
int i;
std::cerr << "called from " << (char*)names[0] << std::endl;
for (i = 1; i < n; ++i)
std::cerr << " " << (char*)names[i] << std::endl;
free (names);
}
}
return(0);
}
#endif //!FREEBSD
#endif //!WIN32
void Unprotect(std::string &s, char what)
{
if (s.length()) {
@@ -48,12 +78,12 @@ void Protect(std::string &s, char what)
*/
bool ItemParse(const char *data, int length, std::map<int,std::map<int,std::string> > &items, int id_pos, int name_pos, int max_field, int level)
{
int i;
char *end,*ptr;
std::map<int,std::string> field;
static char *buffer=nullptr;
static int buffsize=0;
static char *temp=nullptr;
int i;
char *end,*ptr;
std::map<int,std::string> field;
static char *buffer=nullptr;
static int buffsize=0;
static char *temp=nullptr;
if (!buffsize || buffsize<(length+1)) {
buffer=(char *)realloc(buffer,length+1);
temp=(char *)realloc(temp,length+1);
@@ -156,10 +186,10 @@ bool ItemParse(const char *data, int length, std::map<int,std::map<int,std::stri
int Tokenize(std::string s,std::map<int,std::string> & tokens, char delim)
{
int i,len;
std::string::size_type end;
//char temp[1024];
std::string x;
int i,len;
std::string::size_type end;
//char temp[1024];
std::string x;
tokens.clear();
i=0;
while(s.length()) {
@@ -305,14 +335,14 @@ void LoadItemDBFieldNames() {
void encode_length(unsigned long length, char *out)
{
char buf[4];
char buf[4];
memcpy(buf,&length,sizeof(unsigned long));
encode_chunk(buf,3,out);
}
unsigned long encode(char *in, unsigned long length, char *out)
{
unsigned long used=0,len=0;
unsigned long used=0,len=0;
while(used<length) {
encode_chunk(in+used,length-used,out+len);
used+=3;
@@ -325,8 +355,8 @@ unsigned long encode(char *in, unsigned long length, char *out)
unsigned long decode_length(char *in)
{
int length;
char buf[4];
int length;
char buf[4];
decode_chunk(in,&buf[0]);
buf[3]=0;
memcpy(&length,buf,sizeof(unsigned long));
@@ -336,8 +366,8 @@ unsigned long decode_length(char *in)
void decode(char *in, char *out)
{
char *ptr=in;
char *outptr=out;
char *ptr=in;
char *outptr=out;
while(*ptr) {
decode_chunk(ptr,outptr);
ptr+=4;
@@ -363,8 +393,8 @@ void decode_chunk(char *in, char *out)
void dump_message_column(unsigned char *buffer, unsigned long length, std::string leader, FILE *to)
{
unsigned long i,j;
unsigned long rows,offset=0;
unsigned long i,j;
unsigned long rows,offset=0;
rows=(length/16)+1;
for(i=0;i<rows;i++) {
fprintf(to, "%s%05ld: ",leader.c_str(),i*16);
@@ -389,8 +419,8 @@ void dump_message_column(unsigned char *buffer, unsigned long length, std::strin
std::string long2ip(unsigned long ip)
{
char temp[16];
union { unsigned long ip; struct { unsigned char a,b,c,d; } octet;} ipoctet;
char temp[16];
union { unsigned long ip; struct { unsigned char a,b,c,d; } octet;} ipoctet;
ipoctet.ip=ip;
sprintf(temp,"%d.%d.%d.%d",ipoctet.octet.a,ipoctet.octet.b,ipoctet.octet.c,ipoctet.octet.d);
@@ -400,8 +430,8 @@ std::string long2ip(unsigned long ip)
std::string string_from_time(std::string pattern, time_t now)
{
struct tm *now_tm;
char time_string[51];
struct tm *now_tm;
char time_string[51];
if (!now)
time(&now);
@@ -420,9 +450,9 @@ std::string timestamp(time_t now)
std::string pop_arg(std::string &s, std::string seps, bool obey_quotes)
{
std::string ret;
unsigned long i;
bool in_quote=false;
std::string ret;
unsigned long i;
bool in_quote=false;
unsigned long length=s.length();
for(i=0;i<length;i++) {
@@ -451,8 +481,8 @@ std::string pop_arg(std::string &s, std::string seps, bool obey_quotes)
int EQsprintf(char *buffer, const char *pattern, const char *arg1, const char *arg2, const char *arg3, const char *arg4, const char *arg5, const char *arg6, const char *arg7, const char *arg8, const char *arg9)
{
const char *args[9],*ptr;
char *bptr;
const char *args[9],*ptr;
char *bptr;
args[0]=arg1;
args[1]=arg2;
args[2]=arg3;
@@ -494,11 +524,11 @@ int EQsprintf(char *buffer, const char *pattern, const char *arg1, const char *a
std::string generate_key(int length)
{
std::string key;
//TODO: write this for win32...
std::string key;
//TODO: write this for win32...
#ifndef WIN32
int i;
timeval now;
int i;
timeval now;
static const char *chars="ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
for(i=0;i<length;i++) {
gettimeofday(&now,nullptr);
@@ -520,9 +550,9 @@ void print_hex(const char *data, unsigned long length) {
void build_hex_line(const char *buffer, unsigned long length, unsigned long offset, char *out_buffer, unsigned char padding)
{
char *ptr=out_buffer;
int i;
char printable[17];
char *ptr=out_buffer;
int i;
char printable[17];
ptr+=sprintf(ptr,"%0*lu:",padding,offset);
for(i=0;i<16; i++) {
if (i==8) {
+4
View File
@@ -24,6 +24,10 @@ void decode(char *in, char *out);
void encode_chunk(char *in, int len, char *out);
void decode_chunk(char *in, char *out);
#ifndef WIN32
int print_stacktrace();
#endif
void dump_message_column(unsigned char *buffer, unsigned long length, std::string leader="", FILE *to = stdout);
std::string string_from_time(std::string pattern, time_t now=0);
std::string timestamp(time_t now=0);
+1
View File
@@ -32,6 +32,7 @@ MySQLRequestResult::MySQLRequestResult(MYSQL_RES* result, uint32 rowsAffected, u
void MySQLRequestResult::FreeInternals()
{
safe_delete_array(m_ErrorBuffer);
if (m_Result != nullptr)
+3 -3
View File
@@ -180,7 +180,7 @@ IN(OP_GMLastName, GMLastName_Struct);
IN(OP_GMToggle, GMToggle_Struct);
IN(OP_LFGCommand, LFG_Struct);
IN(OP_GMGoto, GMSummon_Struct);
IN(OP_TraderShop, TraderClick_Struct);
INv(OP_TraderShop, TraderClick_Struct);
IN(OP_ShopRequest, Merchant_Click_Struct);
IN(OP_Bazaar, BazaarSearch_Struct);
//alt:IN(OP_Bazaar, BazaarWelcome_Struct); //alternate structure for OP_Bazaar
@@ -399,7 +399,7 @@ OUT(OP_Weather, Weather_Struct);
OUT(OP_ZoneChange, ZoneChange_Struct);
OUT(OP_ZoneInUnknown, ZoneInUnknown_Struct);
//this is the set of opcodes which are allready listed
//this is the set of opcodes which are already listed
//in the IN section above, but are also sent OUT
#ifdef DISJOINT_DIRECTIONS
OUTz(OP_ClientReady); //follows OP_SetServerFilter
@@ -449,7 +449,7 @@ OUT(OP_Trader, TraderBuy_Struct); //3 possible lengths
//alt:OUT(OP_Trader, Trader_ShowItems_Struct);
//alt:OUT(OP_Trader, Trader_Struct);
OUT(OP_TraderBuy, TraderBuy_Struct);
OUT(OP_TraderShop, TraderClick_Struct);
OUTv(OP_TraderShop, TraderClick_Struct);
OUT(OP_WearChange, WearChange_Struct);
OUT(OP_ZoneEntry, ServerZoneEntry_Struct);
#endif
+307
View File
@@ -0,0 +1,307 @@
#include "global_define.h"
#include <map>
#include <string>
std::map<unsigned long, std::string> opcode_map;
std::string get_opcode_name(unsigned long opcode)
{
std::map<unsigned long, std::string>::iterator itr;;
return (itr = opcode_map.find(opcode)) != opcode_map.end() ? itr->second : "OP_Unknown";
}
void load_opcode_names()
{
opcode_map[0x0176] = "LiveOP_Heartbeat";
opcode_map[0x02d7] = "LiveOP_ReloadUI";
opcode_map[0x01eb] = "LiveOP_IncreaseStats";
opcode_map[0x0134] = "LiveOP_ApproveZone";
opcode_map[0x01d5] = "LiveOP_Dye";
opcode_map[0x0168] = "LiveOP_Stamina";
opcode_map[0x014d] = "LiveOP_ControlBoat";
opcode_map[0x003e] = "LiveOP_MobUpdate";
opcode_map[0x0027] = "LiveOP_ClientUpdate";
opcode_map[0x0024] = "LiveOP_ChannelMessage";
opcode_map[0x01d7] = "LiveOP_SimpleMessage";
opcode_map[0x01d8] = "LiveOP_FormattedMessage";
opcode_map[0x01c6] = "LiveOP_TGB";
opcode_map[0x0285] = "LiveOP_TestBuff";
opcode_map[0x012d] = "LiveOP_Bind_Wound";
opcode_map[0x01ab] = "LiveOP_Charm";
opcode_map[0x014c] = "LiveOP_Begging";
opcode_map[0x0152] = "LiveOP_MoveCoin";
opcode_map[0x0292] = "LiveOP_SpawnDoor";
opcode_map[0x009d] = "LiveOP_Sneak";
opcode_map[0x0079] = "LiveOP_ExpUpdate";
opcode_map[0x027d] = "LiveOP_DumpName";
opcode_map[0x01ea] = "LiveOP_RespondAA";
opcode_map[0x01c9] = "LiveOP_SendAAStats";
opcode_map[0x0366] = "LiveOP_SendAATable";
opcode_map[0x01e9] = "LiveOP_AAAction";
opcode_map[0x00bb] = "LiveOP_BoardBoat";
opcode_map[0x00bc] = "LiveOP_LeaveBoat";
opcode_map[0x02b8] = "LiveOP_AdventureInfoRequest";
opcode_map[0x02b9] = "LiveOP_AdventureInfo";
opcode_map[0x02a6] = "LiveOP_AdventureRequest";
opcode_map[0x02a8] = "LiveOP_AdventureDetails";
opcode_map[0x02a9] = "LiveOP_LDoNButton";
opcode_map[0x02ba] = "LiveOP_AdventureData";
opcode_map[0x02c9] = "LiveOP_AdventureFinish";
opcode_map[0x02c6] = "LiveOP_LeaveAdventure";
opcode_map[0x02ce] = "LiveOP_AdventureUpdate";
opcode_map[0x002b] = "LiveOP_SendExpZonein";
opcode_map[0x01e4] = "LiveOP_ZoneInSendName";
opcode_map[0x01bf] = "LiveOP_GuildLeader";
opcode_map[0x009a] = "LiveOP_GuildPeace";
opcode_map[0x0132] = "LiveOP_GuildRemove";
opcode_map[0x0059] = "LiveOP_GuildMemberList";
opcode_map[0x026e] = "LiveOP_GuildMemberUpdate";
opcode_map[0x0130] = "LiveOP_GuildInvite";
opcode_map[0x01c0] = "LiveOP_GuildMOTD";
opcode_map[0x003c] = "LiveOP_GuildPublicNote";
opcode_map[0x027e] = "LiveOP_GetGuildMOTD";
opcode_map[0x0277] = "LiveOP_GuildDemote";
opcode_map[0x0131] = "LiveOP_GuildInviteAccept";
opcode_map[0x00a4] = "LiveOP_GuildWar";
opcode_map[0x0133] = "LiveOP_GuildDelete";
opcode_map[0x0233] = "LiveOP_GuildManageRemove";
opcode_map[0x022d] = "LiveOP_GuildManageAdd";
opcode_map[0x0039] = "LiveOP_GuildManageStatus";
opcode_map[0x01e8] = "LiveOP_Trader";
opcode_map[0x01e7] = "LiveOP_Bazaar";
opcode_map[0x01c4] = "LiveOP_BecomeTrader";
opcode_map[0x01f4] = "LiveOP_BazaarInspect";
opcode_map[0x006e] = "LiveOP_TraderItemUpdate";
opcode_map[0x017c] = "LiveOP_TraderDelItem";
opcode_map[0x01eb] = "LiveOP_TraderShop";
opcode_map[0x01ca] = "LiveOP_TraderBuy";
opcode_map[0x01ac] = "LiveOP_PetCommands";
opcode_map[0x0042] = "LiveOP_TradeSkillCombine";
opcode_map[0x02e5] = "LiveOP_AugmentItem";
opcode_map[0x0367] = "LiveOP_ItemName";
opcode_map[0x02cd] = "LiveOP_ShopItem";
opcode_map[0x0065] = "LiveOP_ShopPlayerBuy";
opcode_map[0x006a] = "LiveOP_ShopPlayerSell";
opcode_map[0x006d] = "LiveOP_ShopDelItem";
opcode_map[0x0f6d] = "LiveOP_ShopEndConfirm";
opcode_map[0x00f7] = "LiveOP_ShopRequest";
opcode_map[0x006c] = "LiveOP_ShopEnd";
opcode_map[0x02d1] = "LiveOP_AdventureMerchantRequest";
opcode_map[0x02d2] = "LiveOP_AdventureMerchantResponse";
opcode_map[0x02d3] = "LiveOP_AdventureMerchantPurchase";
opcode_map[0x02e3] = "LiveOP_AdventurePointsUpdate";
opcode_map[0x0270] = "LiveOP_LFGCommand";
opcode_map[0x01d0] = "LiveOP_LFGAppearance";
opcode_map[0x01b5] = "LiveOP_MoneyUpdate";
opcode_map[0x0721] = "LiveOP_GroupDelete";
opcode_map[0x0272] = "LiveOP_GroupAcknowledge";
opcode_map[0x024a] = "LiveOP_GroupUpdate";
opcode_map[0x025f] = "LiveOP_GroupInvite";
opcode_map[0x00ff] = "LiveOP_GroupDisband";
opcode_map[0x00d5] = "LiveOP_GroupInvite2";
opcode_map[0x025e] = "LiveOP_GroupFollow";
opcode_map[0x00d7] = "LiveOP_GroupFollow2";
opcode_map[0x00d6] = "LiveOP_GroupCancelInvite";
opcode_map[0x0156] = "LiveOP_Split";
opcode_map[0x00d8] = "LiveOP_Jump";
opcode_map[0x01d6] = "LiveOP_ConsiderCorpse";
opcode_map[0x0064] = "LiveOP_SkillUpdate";
opcode_map[0x0178] = "LiveOP_GMEndTrainingResponse";
opcode_map[0x013c] = "LiveOP_GMEndTraining";
opcode_map[0x0175] = "LiveOP_GMTrainSkill";
opcode_map[0x013b] = "LiveOP_GMTraining";
opcode_map[0x017b] = "LiveOP_ConsumeAmmo";
opcode_map[0x0171] = "LiveOP_CombatAbility";
opcode_map[0x009c] = "LiveOP_TrackUnknown";
opcode_map[0x0234] = "LiveOP_TrackTarget";
opcode_map[0x0286] = "LiveOP_Track";
opcode_map[0x0297] = "LiveOP_ReadBook";
opcode_map[0x001f] = "LiveOP_ItemLinkClick";
opcode_map[0x01f4] = "LiveOP_ItemLinkResponse";
opcode_map[0x01d9] = "LiveOP_ItemLinkText";
opcode_map[0x0a41] = "LiveOP_RezzRequest";
opcode_map[0x00e5] = "LiveOP_RezzAnswer";
opcode_map[0x019b] = "LiveOP_RezzComplete";
opcode_map[0x0128] = "LiveOP_MoveDoor";
opcode_map[0x0127] = "LiveOP_ClickDoor";
opcode_map[0x0247] = "LiveOP_SendZonepoints";
opcode_map[0x008c] = "LiveOP_SetRunMode";
opcode_map[0x0248] = "LiveOP_InspectRequest";
opcode_map[0x0249] = "LiveOP_InspectAnswer";
opcode_map[0x0187] = "LiveOP_SenseTraps";
opcode_map[0x018e] = "LiveOP_DisarmTraps";
opcode_map[0x01bc] = "LiveOP_Assist";
opcode_map[0x0240] = "LiveOP_PickPocket";
opcode_map[0x0119] = "LiveOP_LootRequest";
opcode_map[0x011a] = "LiveOP_EndLootRequest";
opcode_map[0x011b] = "LiveOP_MoneyOnCorpse";
opcode_map[0x0179] = "LiveOP_LootComplete";
opcode_map[0x013f] = "LiveOP_LootItem";
opcode_map[0x0151] = "LiveOP_MoveItem";
opcode_map[0x0056] = "LiveOP_WhoAllRequest";
opcode_map[0x0229] = "LiveOP_WhoAllResponse";
opcode_map[0x0167] = "LiveOP_Consume";
opcode_map[0x0172] = "LiveOP_AutoAttack";
opcode_map[0x0186] = "LiveOP_AutoAttack2";
opcode_map[0x0173] = "LiveOP_TargetMouse";
opcode_map[0x01ba] = "LiveOP_TargetCommand";
opcode_map[0x01d8] = "LiveOP_TargetReject";
opcode_map[0x009e] = "LiveOP_Hide";
opcode_map[0x012e] = "LiveOP_Forage";
opcode_map[0x0077] = "LiveOP_Fishing";
opcode_map[0x0246] = "LiveOP_Bug";
opcode_map[0x00f2] = "LiveOP_Emote";
opcode_map[0x0140] = "LiveOP_EmoteAnim";
opcode_map[0x015c] = "LiveOP_Consider";
opcode_map[0x01cb] = "LiveOP_FaceChange";
opcode_map[0x0197] = "LiveOP_RandomReq";
opcode_map[0x0087] = "LiveOP_RandomReply";
opcode_map[0x01c3] = "LiveOP_Camp";
opcode_map[0x0192] = "LiveOP_YellForHelp";
opcode_map[0x00ef] = "LiveOP_SafePoint";
opcode_map[0x0157] = "LiveOP_Buff";
opcode_map[0x00c0] = "LiveOP_ColoredText";
opcode_map[0x0440] = "LiveOP_MultiLineMsg";
opcode_map[0x021c] = "LiveOP_SpecialMesg";
opcode_map[0x0013] = "LiveOP_Consent";
opcode_map[0x029d] = "LiveOP_ConsentResponse";
opcode_map[0x02d4] = "LiveOP_Deny";
opcode_map[0x016c] = "LiveOP_Stun";
opcode_map[0x0021] = "LiveOP_BeginCast";
opcode_map[0x00be] = "LiveOP_CastSpell";
opcode_map[0x01a8] = "LiveOP_InterruptCast";
opcode_map[0x0105] = "LiveOP_Death";
opcode_map[0x023f] = "LiveOP_FeignDeath";
opcode_map[0x012b] = "LiveOP_Illusion";
opcode_map[0x0078] = "LiveOP_LevelUpdate";
opcode_map[0x0371] = "LiveOP_LevelAppearance";
opcode_map[0x00c2] = "LiveOP_MemorizeSpell";
opcode_map[0x0244] = "LiveOP_HPUpdate";
opcode_map[0x022e] = "LiveOP_SendHPTarget";
opcode_map[0x007d] = "LiveOP_Mend";
opcode_map[0x0160] = "LiveOP_Taunt";
opcode_map[0x0199] = "LiveOP_GMDelCorpse";
opcode_map[0x0047] = "LiveOP_GMFind";
opcode_map[0x0020] = "LiveOP_GMServers";
opcode_map[0x010b] = "LiveOP_GMGoto";
opcode_map[0x028c] = "LiveOP_GMSummon";
opcode_map[0x010a] = "LiveOP_GMKick";
opcode_map[0x0109] = "LiveOP_GMKill";
opcode_map[0x0b40] = "LiveOP_GMNameChange";
opcode_map[0x00a3] = "LiveOP_GMLastName";
opcode_map[0x01b3] = "LiveOP_GMToggle";
opcode_map[0x028f] = "LiveOP_GMEmoteZone";
opcode_map[0x0074] = "LiveOP_GMBecomeNPC";
opcode_map[0x00de] = "LiveOP_GMHideMe";
opcode_map[0x0184] = "LiveOP_GMZoneRequest";
opcode_map[0x0239] = "LiveOP_GMZoneRequest2";
opcode_map[0x0068] = "LiveOP_Petition";
opcode_map[0x0085] = "LiveOP_PetitionRefresh";
opcode_map[0x01ee] = "LiveOP_PDeletePetition";
opcode_map[0x0092] = "LiveOP_PetitionBug";
opcode_map[0x0069] = "LiveOP_PetitionUpdate";
opcode_map[0x0076] = "LiveOP_PetitionCheckout";
opcode_map[0x0056] = "LiveOP_PetitionCheckout2";
opcode_map[0x0091] = "LiveOP_PetitionDelete";
opcode_map[0x02b4] = "LiveOP_PetitionResolve";
opcode_map[0x007e] = "LiveOP_PetitionCheckIn";
opcode_map[0x0090] = "LiveOP_PetitionUnCheckout";
opcode_map[0x01ec] = "LiveOP_PetitionQue";
opcode_map[0x01bb] = "LiveOP_SetServerFilter";
opcode_map[0x0218] = "LiveOP_NewSpawn";
opcode_map[0x0140] = "LiveOP_Animation";
opcode_map[0x0142] = "LiveOP_ZoneChange";
opcode_map[0x00f3] = "LiveOP_DeleteSpawn";
opcode_map[0x0265] = "LiveOP_CrashDump";
opcode_map[0x00e8] = "LiveOP_EnvDamage";
opcode_map[0x0101] = "LiveOP_Action";
opcode_map[0x00e2] = "LiveOP_Damage";
opcode_map[0x00bf] = "LiveOP_ManaChange";
opcode_map[0x027c] = "LiveOP_ClientError";
opcode_map[0x00fb] = "LiveOP_Save";
opcode_map[0x0316] = "LiveOP_LocInfo";
opcode_map[0x0188] = "LiveOP_Surname";
opcode_map[0x018f] = "LiveOP_SwapSpell";
opcode_map[0x01db] = "LiveOP_DeleteSpell";
opcode_map[0x029f] = "LiveOP_CloseContainer";
opcode_map[0x029f] = "LiveOP_ClickObjectAck";
opcode_map[0x00fa] = "LiveOP_CreateObject";
opcode_map[0x00f9] = "LiveOP_ClickObject";
opcode_map[0x01c1] = "LiveOP_ClearObject";
opcode_map[0x0265] = "LiveOP_ZoneUnavail";
opcode_map[0x02e0] = "LiveOP_ItemPacket";
opcode_map[0x029a] = "LiveOP_TradeRequest";
opcode_map[0x0037] = "LiveOP_TradeRequestAck";
opcode_map[0x002d] = "LiveOP_TradeAcceptClick";
opcode_map[0x0162] = "LiveOP_TradeMoneyUpdate";
opcode_map[0x0036] = "LiveOP_TradeCoins";
opcode_map[0x002e] = "LiveOP_CancelTrade";
opcode_map[0x002f] = "LiveOP_FinishTrade";
opcode_map[0x00a1] = "LiveOP_SaveOnZoneReq";
opcode_map[0x0185] = "LiveOP_Logout";
opcode_map[0x0298] = "LiveOP_RequestDuel";
opcode_map[0x0a5d] = "LiveOP_DuelResponse";
opcode_map[0x016e] = "LiveOP_DuelResponse2";
opcode_map[0x007c] = "LiveOP_InstillDoubt";
opcode_map[0x00ac] = "LiveOP_SafeFallSuccess";
opcode_map[0x02fb] = "LiveOP_DisciplineUpdate";
opcode_map[0x02f2] = "LiveOP_TributeUpdate";
opcode_map[0x02f3] = "LiveOP_TributeItem";
opcode_map[0x02f4] = "LiveOP_TributePointUpdate";
opcode_map[0x02f5] = "LiveOP_SendTributes";
opcode_map[0x02f6] = "LiveOP_TributeInfo";
opcode_map[0x02f7] = "LiveOP_SelectTribute";
opcode_map[0x02f8] = "LiveOP_TributeTimer";
opcode_map[0x02f9] = "LiveOP_StartTribute";
opcode_map[0x02fa] = "LiveOP_TributeNPC";
opcode_map[0x02fe] = "LiveOP_TributeMoney";
opcode_map[0x0364] = "LiveOP_TributeToggle";
opcode_map[0x0322] = "LiveOP_RecipesFavorite";
opcode_map[0x01f9] = "LiveOP_RecipesSearch";
opcode_map[0x01fa] = "LiveOP_RecipeReply";
opcode_map[0x01fb] = "LiveOP_RecipeDetails";
opcode_map[0x01fc] = "LiveOP_RecipeAutoCombine";
opcode_map[0x02db] = "LiveOP_FindPersonRequest";
opcode_map[0x02dc] = "LiveOP_FindPersonReply";
opcode_map[0x01dd] = "LiveOP_Shielding";
opcode_map[0x0198] = "LiveOP_SetDataRate";
opcode_map[0x023b] = "LiveOP_ZoneEntry";
opcode_map[0x006b] = "LiveOP_PlayerProfile";
opcode_map[0x0291] = "LiveOP_CharInventory";
opcode_map[0x0170] = "LiveOP_ZoneSpawns";
opcode_map[0x0026] = "LiveOP_TimeOfDay";
opcode_map[0x015b] = "LiveOP_Weather";
opcode_map[0x00ec] = "LiveOP_ReqNewZone";
opcode_map[0x00eb] = "LiveOP_NewZone";
opcode_map[0x00fd] = "LiveOP_ReqClientSpawn";
opcode_map[0x012F] = "LiveOP_SpawnAppearance";
opcode_map[0x0086] = "LiveOP_ClientReady";
opcode_map[0x0086] = "LiveOP_ZoneComplete";
opcode_map[0x02db] = "LiveOP_LoginComplete";
opcode_map[0x0195] = "LiveOP_ApproveWorld";
opcode_map[0x035f] = "LiveOP_LogServer";
opcode_map[0x01b2] = "LiveOP_MOTD";
opcode_map[0x0251] = "LiveOP_SendLoginInfo";
opcode_map[0x00ea] = "LiveOP_DeleteCharacter";
opcode_map[0x0102] = "LiveOP_SendCharInfo";
opcode_map[0x00e1] = "LiveOP_ExpansionInfo";
opcode_map[0x0104] = "LiveOP_CharacterCreate";
opcode_map[0x02ab] = "LiveOP_RandomNameGenerator";
opcode_map[0x005d] = "LiveOP_GuildsList";
opcode_map[0x0125] = "LiveOP_ApproveName";
opcode_map[0x0261] = "LiveOP_EnterWorld";
opcode_map[0x015a] = "LiveOP_World_Client_CRC1";
opcode_map[0x015e] = "LiveOP_World_Client_CRC2";
opcode_map[0x0269] = "LiveOP_SetChatServer";
opcode_map[0x0264] = "LiveOP_ZoneServerInfo";
opcode_map[0x0017] = "LiveOP_AckPacket";
opcode_map[0x012c] = "LiveOP_WearChange";
opcode_map[0x1FA1] = "LiveOP_WorldObjectsSent";
opcode_map[0x39C4] = "LiveOP_BlockedBuffs";
opcode_map[0x4656] = "LiveOP_SpawnPositionUpdate";
opcode_map[0x4b61] = "LiveOP_ManaUpdate";
opcode_map[0x02d6] = "LiveOP_EnduranceUpdate";
opcode_map[0x2ac1] = "LiveOP_MobManaUpdate";
opcode_map[0x6c5f] = "LiveOP_MobEnduranceUpdate";
opcode_map[0x73a8] = "LiveOP_SendMaxCharacters";
}
+438
View File
@@ -0,0 +1,438 @@
#ifndef WIN32
#include <unistd.h>
#else
#include <winsock2.h>
#endif
#include <errno.h>
#include <string.h>
#include <time.h>
#include "packetfile.h"
#include "../common/eq_opcodes.h"
#include "../common/eq_packet_structs.h"
#include "../common/misc.h"
#include <map>
PacketFileWriter::PacketFileWriter(bool _force_flush) {
out = NULL;
force_flush = _force_flush;
}
PacketFileWriter::~PacketFileWriter() {
CloseFile();
}
bool PacketFileWriter::SetPacketStamp(const char *name, uint32 stamp) {
FILE *in;
in = fopen(name, "r+b");
if(in == NULL) {
fprintf(stderr, "Error opening packet file '%s': %s\n", name, strerror(errno));
return(false);
}
unsigned long magic = 0;
if(fread(&magic, sizeof(magic), 1, in) != 1) {
fprintf(stderr, "Error reading header from packet file: %s\n", strerror(errno));
fclose(in);
return(false);
}
PacketFileReader *ret = NULL;
if(magic == OLD_PACKET_FILE_MAGIC) {
OldPacketFileHeader *pos = 0;
uint32 stamp_pos = (uint32) &pos->packet_file_stamp;
fseek(in, stamp_pos, SEEK_SET);
OldPacketFileHeader hdr;
hdr.packet_file_stamp = stamp;
if(fwrite(&hdr.packet_file_stamp, sizeof(hdr.packet_file_stamp), 1, in) != 1) {
fprintf(stderr, "Error writting to packet file: %s\n", strerror(errno));
fclose(in);
return(false);
}
} else if(magic == PACKET_FILE_MAGIC) {
PacketFileHeader *pos = 0;
uint32 stamp_pos = (uint32) &pos->packet_file_stamp;
fseek(in, stamp_pos, SEEK_SET);
PacketFileHeader hdr;
hdr.packet_file_stamp = stamp;
if(fwrite(&hdr.packet_file_stamp, sizeof(hdr.packet_file_stamp), 1, in) != 1) {
fprintf(stderr, "Error writting to packet file: %s\n", strerror(errno));
fclose(in);
return(false);
}
} else {
fprintf(stderr, "Unknown packet file type 0x%.8x\n", magic);
fclose(in);
return(false);
}
fclose(in);
return(true);
}
bool PacketFileWriter::OpenFile(const char *name) {
CloseFile();
printf("Opening packet file: %s\n", name);
out = fopen(name, "wb");
if(out == NULL) {
fprintf(stderr, "Error opening packet file '%s': %s\n", name, strerror(errno));
return(false);
}
PacketFileHeader head;
head.packet_file_magic = PACKET_FILE_MAGIC;
head.packet_file_version = PACKET_FILE_CURRENT_VERSION;
head.packet_file_stamp = time(NULL);
if(fwrite(&head, sizeof(head), 1, out) != 1) {
fprintf(stderr, "Error writting header to packet file: %s\n", strerror(errno));
fclose(out);
return(false);
}
return(true);
}
void PacketFileWriter::CloseFile() {
if(out != NULL) {
fclose(out);
out = NULL;
printf("Closed packet file.\n");
}
}
void PacketFileWriter::WritePacket(uint16 eq_op, uint32 packlen, const unsigned char *packet, bool to_server, const struct timeval &tv) {
if(out == NULL)
return;
_WriteBlock(eq_op, packet, packlen, to_server, tv);
/*
Could log only the packets we care about, but this is most of the stream,
so just log them all...
switch(eq_op) {
case OP_NewZone:
case OP_ZoneSpawns:
case OP_NewSpawn:
case OP_MobUpdate:
case OP_ClientUpdate:
case OP_Death:
case OP_DeleteSpawn:
case OP_CastSpell:
case OP_ShopRequest:
case OP_ShopEndConfirm:
case OP_ItemPacket:
_WriteBlock(eq_op, packet, packlen);
default:
return;
}
*/
}
bool PacketFileWriter::_WriteBlock(uint16 eq_op, const void *d, uint16 len, bool to_server, const struct timeval &tv) {
if(out == NULL)
return(false);
PacketFileSection s;
s.opcode = eq_op;
s.len = len;
s.tv_sec = tv.tv_sec;
s.tv_msec = tv.tv_usec/1000;
if(to_server)
SetToServer(s);
else
SetToClient(s);
if(fwrite(&s, sizeof(s), 1, out) != 1) {
fprintf(stderr, "Error writting block header: %s\n", strerror(errno));
return(false);
}
if(fwrite(d, 1, len, out) != len) {
fprintf(stderr, "Error writting block body: %s\n", strerror(errno));
return(false);
}
if(force_flush)
fflush(out);
return(true);
}
PacketFileReader *PacketFileReader::OpenPacketFile(const char *name) {
FILE *in;
in = fopen(name, "rb");
if(in == NULL) {
fprintf(stderr, "Error opening packet file '%s': %s\n", name, strerror(errno));
return(NULL);
}
unsigned long magic = 0;
if(fread(&magic, sizeof(magic), 1, in) != 1) {
fprintf(stderr, "Error reading header to packet file: %s\n", strerror(errno));
fclose(in);
return(NULL);
}
PacketFileReader *ret = NULL;
if(magic == OLD_PACKET_FILE_MAGIC) {
ret = new OldPacketFileReader();
} else if(magic == PACKET_FILE_MAGIC) {
ret = new NewPacketFileReader();
} else {
fprintf(stderr, "Unknown packet file type 0x%.8x\n", magic);
fclose(in);
return(NULL);
}
if(!ret->OpenFile(name)) {
safe_delete(ret);
return(NULL);
}
return(ret);
}
PacketFileReader::PacketFileReader() {
packet_file_stamp = 0;
}
OldPacketFileReader::OldPacketFileReader()
: PacketFileReader()
{
in = NULL;
}
OldPacketFileReader::~OldPacketFileReader() {
CloseFile();
}
bool OldPacketFileReader::OpenFile(const char *name) {
CloseFile();
in = fopen(name, "rb");
if(in == NULL) {
fprintf(stderr, "Error opening packet file '%s': %s\n", name, strerror(errno));
return(false);
}
OldPacketFileHeader head;
if(fread(&head, sizeof(head), 1, in) != 1) {
fprintf(stderr, "Error reading header to packet file: %s\n", strerror(errno));
fclose(in);
return(false);
}
if(head.packet_file_magic != OLD_PACKET_FILE_MAGIC) {
fclose(in);
if(head.packet_file_magic > (OLD_PACKET_FILE_MAGIC)) {
fprintf(stderr, "Error: this is a build file, not a packet file, its allready processed!\n");
} else {
fprintf(stderr, "Error: this is not a packet file!\n");
}
return(false);
}
uint32 now = time(NULL);
if(head.packet_file_stamp > now) {
fprintf(stderr, "Error: invalid timestamp in file. Your clock or the collector's is wrong (%d sec ahead).\n", head.packet_file_stamp-now);
fclose(in);
return(false);
}
packet_file_stamp = head.packet_file_stamp;
return(true);
}
void OldPacketFileReader::CloseFile() {
if(in != NULL) {
fclose(in);
in = NULL;
}
}
bool OldPacketFileReader::ResetFile() {
if(in == NULL)
return(false);
rewind(in);
//gotta read past the header again
OldPacketFileHeader head;
if(fread(&head, sizeof(head), 1, in) != 1) {
return(false);
}
return(true);
}
bool OldPacketFileReader::ReadPacket(uint16 &eq_op, uint32 &packlen, unsigned char *packet, bool &to_server, struct timeval &tv) {
if(in == NULL)
return(false);
if(feof(in))
return(false);
OldPacketFileSection s;
if(fread(&s, sizeof(s), 1, in) != 1) {
if(!feof(in))
fprintf(stderr, "Error reading section header: %s\n", strerror(errno));
return(false);
}
eq_op = s.opcode;
if(packlen < s.len) {
fprintf(stderr, "Packet buffer is too small! %d < %d, skipping\n", packlen, s.len);
fseek(in, s.len, SEEK_CUR);
return(false);
}
if(fread(packet, 1, s.len, in) != s.len) {
if(feof(in))
fprintf(stderr, "Error: EOF encountered when expecting packet data.\n");
else
fprintf(stderr, "Error reading packet body: %s\n", strerror(errno));
return(false);
}
packlen = s.len;
to_server = false;
tv.tv_sec = 0;
tv.tv_usec = 0;
return(true);
}
NewPacketFileReader::NewPacketFileReader()
: PacketFileReader()
{
in = NULL;
}
NewPacketFileReader::~NewPacketFileReader() {
CloseFile();
}
bool NewPacketFileReader::OpenFile(const char *name) {
CloseFile();
in = fopen(name, "rb");
if(in == NULL) {
fprintf(stderr, "Error opening packet file '%s': %s\n", name, strerror(errno));
return(false);
}
PacketFileHeader head;
if(fread(&head, sizeof(head), 1, in) != 1) {
fprintf(stderr, "Error reading header to packet file: %s\n", strerror(errno));
fclose(in);
return(false);
}
if(head.packet_file_magic != PACKET_FILE_MAGIC) {
fclose(in);
if(head.packet_file_magic == (PACKET_FILE_MAGIC+1)) {
fprintf(stderr, "Error: this is a build file, not a packet file, its allready processed!\n");
} else {
fprintf(stderr, "Error: this is not a packet file!\n");
}
return(false);
}
uint32 now = time(NULL);
if(head.packet_file_stamp > now) {
fprintf(stderr, "Error: invalid timestamp in file. Your clock or the collector's is wrong (%d sec ahead).\n", head.packet_file_stamp-now);
fclose(in);
return(false);
}
packet_file_stamp = head.packet_file_stamp;
return(true);
}
void NewPacketFileReader::CloseFile() {
if(in != NULL) {
fclose(in);
in = NULL;
}
}
bool NewPacketFileReader::ResetFile() {
if(in == NULL)
return(false);
rewind(in);
//gotta read past the header again
PacketFileHeader head;
if(fread(&head, sizeof(head), 1, in) != 1) {
return(false);
}
return(true);
}
bool NewPacketFileReader::ReadPacket(uint16 &eq_op, uint32 &packlen, unsigned char *packet, bool &to_server, struct timeval &tv) {
if(in == NULL)
return(false);
if(feof(in))
return(false);
PacketFileSection s;
if(fread(&s, sizeof(s), 1, in) != 1) {
if(!feof(in))
fprintf(stderr, "Error reading section header: %s\n", strerror(errno));
return(false);
}
eq_op = s.opcode;
if(packlen < s.len) {
fprintf(stderr, "Packet buffer is too small! %d < %d, skipping\n", packlen, s.len);
fseek(in, s.len, SEEK_CUR);
return(false);
}
if(fread(packet, 1, s.len, in) != s.len) {
if(feof(in))
fprintf(stderr, "Error: EOF encountered when expecting packet data.\n");
else
fprintf(stderr, "Error reading packet body: %s\n", strerror(errno));
return(false);
}
packlen = s.len;
to_server = IsToServer(s);
tv.tv_sec = s.tv_sec;
tv.tv_usec = 1000*s.tv_msec;
return(true);
}
+130
View File
@@ -0,0 +1,130 @@
#ifndef PACKET_FILE_H
#define PACKET_FILE_H
#include "../common/types.h"
#include <stdio.h>
#include <time.h>
//#include <zlib.h>
//constants used in the packet file header
#define PACKET_FILE_MAGIC 0x93a7b6f6
#define OLD_PACKET_FILE_MAGIC 0x93a7b6f7
#define PACKET_FILE_CURRENT_VERSION 1
#pragma pack(1)
//old structs from when I forgot to put the version number in
struct OldPacketFileHeader {
uint32 packet_file_magic;
uint32 packet_file_stamp;
};
struct OldPacketFileSection {
uint16 opcode;
uint32 len;
};
struct PacketFileHeader {
uint32 packet_file_magic;
uint16 packet_file_version;
uint32 packet_file_stamp;
};
struct PacketFileSection {
uint16 opcode;
uint8 flags; //mainly for client->server, but others could be added
uint32 tv_sec;
uint16 tv_msec;
uint32 len;
};
#pragma pack()
#define TO_SERVER_FLAG 0x01
#define SetToClient(pfs) pfs.flags = pfs.flags&~TO_SERVER_FLAG
#define SetToServer(pfs) pfs.flags = pfs.flags|TO_SERVER_FLAG
#define IsToClient(pfs) (pfs.flags&TO_SERVER_FLAG == 0)
#define IsToServer(pfs) (pfs.flags&TO_SERVER_FLAG != 0)
class PacketFileWriter {
public:
PacketFileWriter(bool force_flush);
~PacketFileWriter();
bool OpenFile(const char *name);
void CloseFile();
void WritePacket(uint16 eq_op, uint32 packlen, const unsigned char *packet, bool to_server, const struct timeval &tv);
static bool SetPacketStamp(const char *file, uint32 stamp);
protected:
bool _WriteBlock(uint16 eq_op, const void *d, uint16 len, bool to_server, const struct timeval &tv);
//gzFile out;
FILE *out;
bool force_flush;
};
class PacketFileReader {
public:
PacketFileReader();
virtual bool OpenFile(const char *name) = 0;
virtual void CloseFile() = 0;
virtual bool ResetFile() = 0; //aka rewind
virtual bool ReadPacket(uint16 &eq_op, uint32 &packlen, unsigned char *packet, bool &to_server, struct timeval &tv) = 0;
time_t GetStamp() { return(time_t(packet_file_stamp)); }
//factory method to open the right packet file.
static PacketFileReader *OpenPacketFile(const char *name);
protected:
uint32 packet_file_stamp;
};
class OldPacketFileReader : public PacketFileReader {
public:
OldPacketFileReader();
virtual ~OldPacketFileReader();
bool OpenFile(const char *name);
void CloseFile();
bool ResetFile(); //aka rewind
bool ReadPacket(uint16 &eq_op, uint32 &packlen, unsigned char *packet, bool &to_server, struct timeval &tv);
time_t GetStamp() { return(time_t(packet_file_stamp)); }
protected:
//gzFile in;
FILE *in;
};
class NewPacketFileReader: public PacketFileReader {
public:
NewPacketFileReader();
virtual ~NewPacketFileReader();
bool OpenFile(const char *name);
void CloseFile();
bool ResetFile(); //aka rewind
bool ReadPacket(uint16 &eq_op, uint32 &packlen, unsigned char *packet, bool &to_server, struct timeval &tv);
time_t GetStamp() { return(time_t(packet_file_stamp)); }
protected:
//gzFile in;
FILE *in;
};
#endif
+258 -191
View File
@@ -15,6 +15,8 @@
#include <iostream>
#include <sstream>
#include <numeric>
#include <cassert>
namespace RoF
{
@@ -225,8 +227,8 @@ namespace RoF
SETUP_DIRECT_ENCODE(Animation_Struct, structs::Animation_Struct);
OUT(spawnid);
OUT(value);
OUT(action);
OUT(speed);
FINISH_ENCODE();
}
@@ -415,7 +417,7 @@ namespace RoF
outapp->WriteUInt32(0); // Duration
outapp->WriteUInt32(0); // ?
outapp->WriteUInt8(0); // Caster name
outapp->WriteUInt8(0); // Terminating byte
outapp->WriteUInt8(0); // Type
}
FINISH_ENCODE();
@@ -452,7 +454,7 @@ namespace RoF
__packet->WriteUInt32(emu->entries[i].num_hits); // Unknown
__packet->WriteString("");
}
__packet->WriteUInt8(!emu->all_buffs); // Unknown
__packet->WriteUInt8(emu->type); // Unknown
FINISH_ENCODE();
}
@@ -477,7 +479,7 @@ namespace RoF
eq->slot = 13;
else
OUT(slot);
OUT(spell_id);
eq->inventoryslot = ServerToRoFSlot(emu->inventoryslot);
//OUT(inventoryslot);
@@ -656,7 +658,9 @@ namespace RoF
OUT(type);
OUT(spellid);
OUT(damage);
eq->sequence = emu->sequence;
OUT(force)
OUT(meleepush_xy);
OUT(meleepush_z)
FINISH_ENCODE();
}
@@ -700,7 +704,7 @@ namespace RoF
{
SETUP_VAR_ENCODE(ExpeditionCompass_Struct);
ALLOC_VAR_ENCODE(structs::ExpeditionCompass_Struct, sizeof(structs::ExpeditionInfo_Struct) + sizeof(structs::ExpeditionCompassEntry_Struct) * emu->count);
OUT(count);
for (uint32 i = 0; i < emu->count; ++i)
@@ -971,8 +975,8 @@ namespace RoF
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); // Normally 0, but seen (float)255.0 as well
VARSTRUCT_ENCODE_TYPE(float, OutBuffer, 0); // Unknown
VARSTRUCT_ENCODE_TYPE(float, OutBuffer, 1); // Need to add emu->size to struct
VARSTRUCT_ENCODE_TYPE(uint32, OutBuffer, emu->solidtype); // Unknown
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);
VARSTRUCT_ENCODE_TYPE(float, OutBuffer, emu->z);
@@ -1247,7 +1251,7 @@ namespace RoF
switch (emu_e->rank) {
case 0: { e->rank = htonl(5); break; } // GUILD_MEMBER 0
case 1: { e->rank = htonl(3); break; } // GUILD_OFFICER 1
case 2: { e->rank = htonl(1); break; } // GUILD_LEADER 2
case 2: { e->rank = htonl(1); break; } // GUILD_LEADER 2
default: { e->rank = htonl(emu_e->rank); break; } // GUILD_NONE
}
@@ -2043,7 +2047,7 @@ namespace RoF
for (int r = 0; r < 7; r++)
{
outapp->WriteUInt32(emu->item_tint[r].color);
outapp->WriteUInt32(emu->item_tint[r].Color);
}
// Write zeroes for extra two tint values
outapp->WriteUInt32(0);
@@ -2053,7 +2057,7 @@ namespace RoF
for (int r = 0; r < 7; r++)
{
outapp->WriteUInt32(emu->item_tint[r].color);
outapp->WriteUInt32(emu->item_tint[r].Color);
}
// Write zeroes for extra two tint values
outapp->WriteUInt32(0);
@@ -2116,7 +2120,7 @@ namespace RoF
{
outapp->WriteUInt32(emu->aa_array[r].AA);
outapp->WriteUInt32(emu->aa_array[r].value);
outapp->WriteUInt32(0);
outapp->WriteUInt32(emu->aa_array[r].charges);
}
// Fill the other 60 AAs with zeroes
@@ -2286,46 +2290,52 @@ namespace RoF
outapp->WriteUInt8(0); // Unknown
outapp->WriteUInt8(0); // Unknown
outapp->WriteUInt32(structs::MAX_PLAYER_BANDOLIER);
outapp->WriteUInt32(consts::BANDOLIERS_SIZE);
for (uint32 r = 0; r < EmuConstants::BANDOLIERS_COUNT; r++)
{
outapp->WriteString(emu->bandoliers[r].name);
for (uint32 j = 0; j < EmuConstants::BANDOLIER_SIZE; ++j)
{
outapp->WriteString(emu->bandoliers[r].items[j].item_name);
outapp->WriteUInt32(emu->bandoliers[r].items[j].item_id);
outapp->WriteUInt32(emu->bandoliers[r].items[j].icon);
// Copy bandoliers where server and client indexes converge
for (uint32 r = 0; r < EmuConstants::BANDOLIERS_SIZE && r < consts::BANDOLIERS_SIZE; ++r) {
outapp->WriteString(emu->bandoliers[r].Name);
for (uint32 j = 0; j < consts::BANDOLIER_ITEM_COUNT; ++j) { // Will need adjusting if 'server != client' is ever true
outapp->WriteString(emu->bandoliers[r].Items[j].Name);
outapp->WriteUInt32(emu->bandoliers[r].Items[j].ID);
if (emu->bandoliers[r].Items[j].Icon) {
outapp->WriteSInt32(emu->bandoliers[r].Items[j].Icon);
}
else {
// If no icon, it must send -1 or Treasure Chest Icon (836) is displayed
outapp->WriteSInt32(-1);
}
}
}
for (uint32 r = 0; r < structs::MAX_PLAYER_BANDOLIER - EmuConstants::BANDOLIERS_COUNT; r++)
{
// Nullify bandoliers where server and client indexes diverge, with a client bias
for (uint32 r = EmuConstants::BANDOLIERS_SIZE; r < consts::BANDOLIERS_SIZE; ++r) {
outapp->WriteString("");
for (uint32 j = 0; j < EmuConstants::BANDOLIER_SIZE; ++j)
{
for (uint32 j = 0; j < consts::BANDOLIER_ITEM_COUNT; ++j) { // Will need adjusting if 'server != client' is ever true
outapp->WriteString("");
outapp->WriteUInt32(0);
outapp->WriteUInt32(0);
outapp->WriteSInt32(-1);
}
}
outapp->WriteUInt32(structs::MAX_POTIONS_IN_BELT);
outapp->WriteUInt32(consts::POTION_BELT_ITEM_COUNT);
for (uint32 r = 0; r < EmuConstants::POTION_BELT_SIZE; r++)
{
outapp->WriteString(emu->potionbelt.items[r].item_name);
outapp->WriteUInt32(emu->potionbelt.items[r].item_id);
outapp->WriteUInt32(emu->potionbelt.items[r].icon);
// Copy potion belt where server and client indexes converge
for (uint32 r = 0; r < EmuConstants::POTION_BELT_ITEM_COUNT && r < consts::POTION_BELT_ITEM_COUNT; ++r) {
outapp->WriteString(emu->potionbelt.Items[r].Name);
outapp->WriteUInt32(emu->potionbelt.Items[r].ID);
if (emu->potionbelt.Items[r].Icon) {
outapp->WriteSInt32(emu->potionbelt.Items[r].Icon);
}
else {
// If no icon, it must send -1 or Treasure Chest Icon (836) is displayed
outapp->WriteSInt32(-1);
}
}
for (uint32 r = 0; r < structs::MAX_POTIONS_IN_BELT - EmuConstants::POTION_BELT_SIZE; r++)
{
// Nullify potion belt where server and client indexes diverge, with a client bias
for (uint32 r = EmuConstants::POTION_BELT_ITEM_COUNT; r < consts::POTION_BELT_ITEM_COUNT; ++r) {
outapp->WriteString("");
outapp->WriteUInt32(0);
outapp->WriteUInt32(0);
outapp->WriteSInt32(-1);
}
outapp->WriteSInt32(-1); // Unknown;
@@ -2418,7 +2428,7 @@ namespace RoF
outapp->WriteUInt32(emu->silver_bank);
outapp->WriteUInt32(emu->copper_bank);
outapp->WriteUInt32(0); // Unknown
outapp->WriteUInt32(emu->platinum_shared);
outapp->WriteUInt32(0); // Unknown
outapp->WriteUInt32(0); // Unknown
outapp->WriteUInt32(0); // Unknown
@@ -2808,9 +2818,9 @@ namespace RoF
for (uint32 i = 0; i < MAX_PP_AA_ARRAY; ++i)
{
eq->aa_list[i].aa_skill = emu->aa_list[i].aa_skill;
eq->aa_list[i].aa_value = emu->aa_list[i].aa_value;
eq->aa_list[i].unknown08 = emu->aa_list[i].unknown08;
eq->aa_list[i].AA = emu->aa_list[i].AA;
eq->aa_list[i].value = emu->aa_list[i].value;
eq->aa_list[i].charges = emu->aa_list[i].charges;
}
FINISH_ENCODE();
@@ -2842,7 +2852,7 @@ namespace RoF
// Check clientver field to verify this AA should be sent for SoF
// clientver 1 is for all clients and 5 is for Live
if (emu->clientver <= 5)
if (emu->clientver <= 7)
{
OUT(id);
eq->unknown004 = 1;
@@ -2858,9 +2868,9 @@ namespace RoF
OUT(cost);
OUT(seq);
OUT(current_level);
eq->unknown037 = 1; // Introduced during HoT
eq->prereq_skill_count = 1; // min 1
OUT(prereq_skill);
eq->unknown045 = 1; // New Mar 21 2012 - Seen 1
eq->prereq_minpoints_count = 1; // min 1
OUT(prereq_minpoints);
eq->type = emu->sof_type;
OUT(spellid);
@@ -2876,6 +2886,7 @@ namespace RoF
OUT(cost2);
eq->aa_expansion = emu->aa_expansion;
eq->special_category = emu->special_category;
eq->expendable_charges = emu->special_category == 7 ? 1 : 0; // temp hack, this can actually be any number
OUT(total_abilities);
unsigned int r;
for (r = 0; r < emu->total_abilities; r++) {
@@ -2891,85 +2902,100 @@ namespace RoF
ENCODE(OP_SendCharInfo)
{
ENCODE_LENGTH_EXACT(CharacterSelect_Struct);
ENCODE_LENGTH_ATLEAST(CharacterSelect_Struct);
SETUP_VAR_ENCODE(CharacterSelect_Struct);
//EQApplicationPacket *packet = *p;
//const CharacterSelect_Struct *emu = (CharacterSelect_Struct *) packet->pBuffer;
// Zero-character count shunt
if (emu->CharCount == 0) {
ALLOC_VAR_ENCODE(structs::CharacterSelect_Struct, sizeof(structs::CharacterSelect_Struct));
eq->CharCount = emu->CharCount;
int char_count;
int namelen = 0;
for (char_count = 0; char_count < 10; char_count++) {
if (emu->name[char_count][0] == '\0')
break;
if (strcmp(emu->name[char_count], "<none>") == 0)
break;
namelen += strlen(emu->name[char_count]);
FINISH_ENCODE();
return;
}
int total_length = sizeof(structs::CharacterSelect_Struct)
+ char_count * sizeof(structs::CharacterSelectEntry_Struct)
+ namelen;
unsigned char *emu_ptr = __emu_buffer;
emu_ptr += sizeof(CharacterSelect_Struct);
CharacterSelectEntry_Struct *emu_cse = (CharacterSelectEntry_Struct *)nullptr;
size_t names_length = 0;
size_t character_count = 0;
for (; character_count < emu->CharCount && character_count < consts::CHARACTER_CREATION_LIMIT; ++character_count) {
emu_cse = (CharacterSelectEntry_Struct *)emu_ptr;
names_length += strlen(emu_cse->Name);
emu_ptr += sizeof(CharacterSelectEntry_Struct);
}
size_t total_length = sizeof(structs::CharacterSelect_Struct)
+ character_count * sizeof(structs::CharacterSelectEntry_Struct)
+ names_length;
ALLOC_VAR_ENCODE(structs::CharacterSelect_Struct, total_length);
structs::CharacterSelectEntry_Struct *eq_cse = (structs::CharacterSelectEntry_Struct *)nullptr;
//unsigned char *eq_buffer = new unsigned char[total_length];
//structs::CharacterSelect_Struct *eq_head = (structs::CharacterSelect_Struct *) eq_buffer;
eq->CharCount = character_count;
//eq->TotalChars = emu->TotalChars;
eq->char_count = char_count;
//eq->total_chars = 10;
//if (eq->TotalChars > consts::CHARACTER_CREATION_LIMIT)
// eq->TotalChars = consts::CHARACTER_CREATION_LIMIT;
unsigned char *bufptr = (unsigned char *)eq->entries;
int r;
for (r = 0; r < char_count; r++) {
{ //pre-name section...
structs::CharacterSelectEntry_Struct *eq2 = (structs::CharacterSelectEntry_Struct *) bufptr;
memcpy(eq2->name, emu->name[r], strlen(emu->name[r]) + 1);
emu_ptr = __emu_buffer;
emu_ptr += sizeof(CharacterSelect_Struct);
unsigned char *eq_ptr = __packet->pBuffer;
eq_ptr += sizeof(structs::CharacterSelect_Struct);
for (int counter = 0; counter < character_count; ++counter) {
emu_cse = (CharacterSelectEntry_Struct *)emu_ptr;
eq_cse = (structs::CharacterSelectEntry_Struct *)eq_ptr; // base address
strcpy(eq_cse->Name, emu_cse->Name);
eq_ptr += strlen(emu_cse->Name);
eq_cse = (structs::CharacterSelectEntry_Struct *)eq_ptr; // offset address (base + name length offset)
eq_cse->Name[0] = '\0'; // (offset)eq_cse->Name[0] = (base)eq_cse->Name[strlen(emu_cse->Name)]
eq_cse->Class = emu_cse->Class;
eq_cse->Race = emu_cse->Race;
eq_cse->Level = emu_cse->Level;
eq_cse->ShroudClass = emu_cse->ShroudClass;
eq_cse->ShroudRace = emu_cse->ShroudRace;
eq_cse->Zone = emu_cse->Zone;
eq_cse->Instance = emu_cse->Instance;
eq_cse->Gender = emu_cse->Gender;
eq_cse->Face = emu_cse->Face;
for (int equip_index = 0; equip_index < _MaterialCount; 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;
}
//adjust for name.
bufptr += strlen(emu->name[r]);
{ //post-name section...
structs::CharacterSelectEntry_Struct *eq2 = (structs::CharacterSelectEntry_Struct *) bufptr;
eq2->class_ = emu->class_[r];
eq2->race = emu->race[r];
eq2->level = emu->level[r];
eq2->class_2 = emu->class_[r];
eq2->race2 = emu->race[r];
eq2->zone = emu->zone[r];
eq2->instance = 0;
eq2->gender = emu->gender[r];
eq2->face = emu->face[r];
int k;
for (k = 0; k < _MaterialCount; k++) {
eq2->equip[k].material = emu->equip[r][k].material;
eq2->equip[k].unknown1 = emu->equip[r][k].unknown1;
eq2->equip[k].elitematerial = emu->equip[r][k].elitematerial;
eq2->equip[k].heroforgemodel = emu->equip[r][k].heroforgemodel;
eq2->equip[k].material2 = emu->equip[r][k].material2;
eq2->equip[k].color.color = emu->equip[r][k].color.color;
}
eq2->u15 = 0xff;
eq2->u19 = 0xFF;
eq2->drakkin_tattoo = emu->drakkin_tattoo[r];
eq2->drakkin_details = emu->drakkin_details[r];
eq2->deity = emu->deity[r];
eq2->primary = emu->primary[r];
eq2->secondary = emu->secondary[r];
eq2->haircolor = emu->haircolor[r];
eq2->beardcolor = emu->beardcolor[r];
eq2->eyecolor1 = emu->eyecolor1[r];
eq2->eyecolor2 = emu->eyecolor2[r];
eq2->hairstyle = emu->hairstyle[r];
eq2->beard = emu->beard[r];
eq2->char_enabled = 1;
eq2->tutorial = emu->tutorial[r];
eq2->drakkin_heritage = emu->drakkin_heritage[r];
eq2->unknown1 = 0;
eq2->gohome = emu->gohome[r];
eq2->LastLogin = 1212696584;
eq2->unknown2 = 0;
}
bufptr += sizeof(structs::CharacterSelectEntry_Struct);
eq_cse->Unknown15 = emu_cse->Unknown15;
eq_cse->Unknown19 = emu_cse->Unknown19;
eq_cse->DrakkinTattoo = emu_cse->DrakkinTattoo;
eq_cse->DrakkinDetails = emu_cse->DrakkinDetails;
eq_cse->Deity = emu_cse->Deity;
eq_cse->PrimaryIDFile = emu_cse->PrimaryIDFile;
eq_cse->SecondaryIDFile = emu_cse->SecondaryIDFile;
eq_cse->HairColor = emu_cse->HairColor;
eq_cse->BeardColor = emu_cse->BeardColor;
eq_cse->EyeColor1 = emu_cse->EyeColor1;
eq_cse->EyeColor2 = emu_cse->EyeColor2;
eq_cse->HairStyle = emu_cse->HairStyle;
eq_cse->Beard = emu_cse->Beard;
eq_cse->GoHome = emu_cse->GoHome;
eq_cse->Tutorial = emu_cse->Tutorial;
eq_cse->DrakkinHeritage = emu_cse->DrakkinHeritage;
eq_cse->Unknown1 = emu_cse->Unknown1;
eq_cse->Enabled = emu_cse->Enabled;
eq_cse->LastLogin = emu_cse->LastLogin;
eq_cse->Unknown2 = emu_cse->Unknown2;
emu_ptr += sizeof(CharacterSelectEntry_Struct);
eq_ptr += sizeof(structs::CharacterSelectEntry_Struct);
}
FINISH_ENCODE();
@@ -3024,7 +3050,7 @@ namespace RoF
switch (emu->Rank) {
case 0: { eq->Rank = 5; break; } // GUILD_MEMBER 0
case 1: { eq->Rank = 3; break; } // GUILD_OFFICER 1
case 2: { eq->Rank = 1; break; } // GUILD_LEADER 2
case 2: { eq->Rank = 1; break; } // GUILD_LEADER 2
default: { eq->Rank = emu->Rank; break; }
}
@@ -3291,7 +3317,7 @@ namespace RoF
delete[] __emu_buffer;
dest->FastQueuePacket(&in, ack_req);
#if 0 // original code
EQApplicationPacket *in = *p;
*p = nullptr;
@@ -3588,37 +3614,71 @@ namespace RoF
FINISH_ENCODE();
}
ENCODE(OP_VetClaimReply)
{
ENCODE_LENGTH_EXACT(VeteranClaim);
SETUP_DIRECT_ENCODE(VeteranClaim, structs::VeteranClaim);
memcpy(eq->name, emu->name, sizeof(emu->name));
OUT(claim_id);
OUT(action);
FINISH_ENCODE();
}
ENCODE(OP_VetRewardsAvaliable)
{
EQApplicationPacket *inapp = *p;
unsigned char * __emu_buffer = inapp->pBuffer;
auto __emu_buffer = inapp->pBuffer;
uint32 count = ((*p)->Size() / sizeof(InternalVeteranReward));
*p = nullptr;
EQApplicationPacket *outapp_create = new EQApplicationPacket(OP_VetRewardsAvaliable, (sizeof(structs::VeteranReward)*count));
uchar *old_data = __emu_buffer;
uchar *data = outapp_create->pBuffer;
for (unsigned int i = 0; i < count; ++i)
{
structs::VeteranReward *vr = (structs::VeteranReward*)data;
InternalVeteranReward *ivr = (InternalVeteranReward*)old_data;
// calculate size of names, note the packet DOES NOT have null termed c-strings
std::vector<uint32> name_lengths;
for (int i = 0; i < count; ++i) {
InternalVeteranReward *ivr = (InternalVeteranReward *)__emu_buffer;
vr->claim_count = ivr->claim_count;
vr->claim_id = ivr->claim_id;
vr->number_available = ivr->number_available;
for (int x = 0; x < 8; ++x)
{
vr->items[x].item_id = ivr->items[x].item_id;
strncpy(vr->items[x].item_name, ivr->items[x].item_name, sizeof(vr->items[x].item_name));
vr->items[x].charges = ivr->items[x].charges;
for (int i = 0; i < ivr->claim_count; i++) {
uint32 length = strnlen(ivr->items[i].item_name, 63);
if (length)
name_lengths.push_back(length);
}
old_data += sizeof(InternalVeteranReward);
data += sizeof(structs::VeteranReward);
__emu_buffer += sizeof(InternalVeteranReward);
}
dest->FastQueuePacket(&outapp_create);
uint32 packet_size = std::accumulate(name_lengths.begin(), name_lengths.end(), 0) +
sizeof(structs::VeteranReward) + (sizeof(structs::VeteranRewardEntry) * count) +
// size of name_lengths is the same as item count
(sizeof(structs::VeteranRewardItem) * name_lengths.size());
// build packet now!
auto outapp = new EQApplicationPacket(OP_VetRewardsAvaliable, packet_size);
__emu_buffer = inapp->pBuffer;
outapp->WriteUInt32(count);
auto name_itr = name_lengths.begin();
for (int i = 0; i < count; i++) {
InternalVeteranReward *ivr = (InternalVeteranReward *)__emu_buffer;
outapp->WriteUInt32(ivr->claim_id);
outapp->WriteUInt32(ivr->number_available);
outapp->WriteUInt32(ivr->claim_count);
outapp->WriteUInt8(1); // enabled
for (int j = 0; j < ivr->claim_count; j++) {
assert(name_itr != name_lengths.end()); // the way it's written, it should never happen, so just assert
outapp->WriteUInt32(*name_itr);
outapp->WriteData(ivr->items[j].item_name, *name_itr);
outapp->WriteUInt32(ivr->items[j].item_id);
outapp->WriteUInt32(ivr->items[j].charges);
++name_itr;
}
__emu_buffer += sizeof(InternalVeteranReward);
}
dest->FastQueuePacket(&outapp);
delete inapp;
}
@@ -3633,7 +3693,7 @@ namespace RoF
OUT(elite_material);
OUT(hero_forge_model);
OUT(unknown18);
OUT(color.color);
OUT(color.Color);
OUT(wear_slot_id);
FINISH_ENCODE();
@@ -3721,45 +3781,26 @@ namespace RoF
}
ENCODE(OP_ZoneEntry) { ENCODE_FORWARD(OP_ZoneSpawns); }
ENCODE(OP_ZonePlayerToBind)
{
ENCODE_LENGTH_ATLEAST(ZonePlayerToBind_Struct);
SETUP_VAR_ENCODE(ZonePlayerToBind_Struct);
ALLOC_LEN_ENCODE(sizeof(structs::ZonePlayerToBind_Struct) + strlen(emu->zone_name));
ZonePlayerToBind_Struct *zps = (ZonePlayerToBind_Struct*)(*p)->pBuffer;
__packet->SetWritePosition(0);
__packet->WriteUInt16(emu->bind_zone_id);
__packet->WriteUInt16(emu->bind_instance_id);
__packet->WriteFloat(emu->x);
__packet->WriteFloat(emu->y);
__packet->WriteFloat(emu->z);
__packet->WriteFloat(emu->heading);
__packet->WriteString(emu->zone_name);
__packet->WriteUInt8(1); // save items
__packet->WriteUInt32(0); // hp
__packet->WriteUInt32(0); // mana
__packet->WriteUInt32(0); // endurance
std::stringstream ss(std::stringstream::in | std::stringstream::out | std::stringstream::binary);
unsigned char *buffer1 = new unsigned char[sizeof(structs::ZonePlayerToBindHeader_Struct) + strlen(zps->zone_name)];
structs::ZonePlayerToBindHeader_Struct *zph = (structs::ZonePlayerToBindHeader_Struct*)buffer1;
unsigned char *buffer2 = new unsigned char[sizeof(structs::ZonePlayerToBindFooter_Struct)];
structs::ZonePlayerToBindFooter_Struct *zpf = (structs::ZonePlayerToBindFooter_Struct*)buffer2;
zph->x = zps->x;
zph->y = zps->y;
zph->z = zps->z;
zph->heading = zps->heading;
zph->bind_zone_id = 0;
zph->bind_instance_id = zps->bind_instance_id;
strncpy(zph->zone_name, zps->zone_name, sizeof(zph->zone_name));
zpf->unknown021 = 1;
zpf->unknown022 = 0;
zpf->unknown023 = 0;
zpf->unknown024 = 0;
ss.write((const char*)buffer1, (sizeof(structs::ZonePlayerToBindHeader_Struct) + strlen(zps->zone_name)));
ss.write((const char*)buffer2, sizeof(structs::ZonePlayerToBindFooter_Struct));
delete[] buffer1;
delete[] buffer2;
delete[](*p)->pBuffer;
(*p)->pBuffer = new unsigned char[ss.str().size()];
(*p)->size = ss.str().size();
memcpy((*p)->pBuffer, ss.str().c_str(), ss.str().size());
dest->FastQueuePacket(&(*p));
FINISH_ENCODE();
}
ENCODE(OP_ZoneServerInfo)
@@ -3807,8 +3848,8 @@ namespace RoF
PacketSize += strlen(emu->name);
PacketSize += strlen(emu->lastName);
emu->title[0] = 0;
emu->suffix[0] = 0;
emu->title[31] = 0;
emu->suffix[31] = 0;
if (strlen(emu->title))
PacketSize += strlen(emu->title) + 1;
@@ -3931,8 +3972,8 @@ namespace RoF
switch (emu->guildrank) {
case 0: { VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 5); break; } // GUILD_MEMBER 0
case 1: { VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 3); break; } // GUILD_OFFICER 1
case 2: { VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 1); break; } // GUILD_LEADER 2
default: { VARSTRUCT_ENCODE_TYPE(uint32, Buffer, emu->guildrank); break; } //
case 2: { VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 1); break; } // GUILD_LEADER 2
default: { VARSTRUCT_ENCODE_TYPE(uint32, Buffer, emu->guildrank); break; } //
}
}
@@ -3951,7 +3992,7 @@ namespace RoF
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, emu->petOwnerId);
VARSTRUCT_ENCODE_TYPE(uint8, Buffer, 0); // unknown13
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0); // unknown14 - Stance 64 = normal 4 = aggressive 40 = stun/mezzed
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, emu->PlayerState);
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0); // unknown15
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0); // unknown16
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0); // unknown17
@@ -3963,18 +4004,18 @@ namespace RoF
for (k = 0; k < 9; ++k)
{
{
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, emu->colors[k].color);
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, emu->colors[k].Color);
}
}
structs::EquipStruct *Equipment = (structs::EquipStruct *)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;
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;
}
Buffer += (sizeof(structs::EquipStruct) * 9);
@@ -3987,13 +4028,13 @@ namespace RoF
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0);
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0);
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, emu->equipment[MaterialPrimary].material);
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, emu->equipment[MaterialPrimary].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[MaterialSecondary].material);
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, emu->equipment[MaterialSecondary].Material);
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0);
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0);
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0);
@@ -4081,6 +4122,18 @@ namespace RoF
FINISH_DIRECT_DECODE();
}
DECODE(OP_Animation)
{
DECODE_LENGTH_EXACT(structs::Animation_Struct);
SETUP_DIRECT_DECODE(Animation_Struct, structs::Animation_Struct);
IN(spawnid);
IN(action);
IN(speed);
FINISH_DIRECT_DECODE();
}
DECODE(OP_ApplyPoison)
{
DECODE_LENGTH_EXACT(structs::ApplyPoison_Struct);
@@ -4193,12 +4246,16 @@ namespace RoF
emu->slot = 10;
else
IN(slot);
IN(spell_id);
emu->inventoryslot = RoFToServerSlot(eq->inventoryslot);
//IN(inventoryslot);
IN(target_id);
IN(y_pos);
IN(x_pos);
IN(z_pos);
FINISH_DIRECT_DECODE();
}
@@ -4336,7 +4393,7 @@ namespace RoF
IN(type);
IN(spellid);
IN(damage);
emu->sequence = eq->sequence;
IN(meleepush_xy);
FINISH_DIRECT_DECODE();
}
@@ -4664,7 +4721,7 @@ namespace RoF
SETUP_DIRECT_DECODE(PetCommand_Struct, structs::PetCommand_Struct);
IN(command);
emu->unknown = eq->unknown04;
IN(target);
FINISH_DIRECT_DECODE();
}
@@ -4888,7 +4945,7 @@ namespace RoF
slot_id = legacy::SLOT_TRADESKILL; // 1000
}
emu->container_slot = slot_id;
emu->guildtribute_slot = RoFToServerSlot(eq->guildtribute_slot); // this should only return INVALID_INDEX until implemented -U
emu->guildtribute_slot = RoFToServerSlot(eq->guildtribute_slot); // this should only return INVALID_INDEX until implemented
FINISH_DIRECT_DECODE();
}
@@ -4923,6 +4980,16 @@ namespace RoF
FINISH_DIRECT_DECODE();
}
DECODE(OP_VetClaimRequest)
{
DECODE_LENGTH_EXACT(structs::VeteranClaim);
SETUP_DIRECT_DECODE(VeteranClaim, structs::VeteranClaim);
IN(claim_id);
FINISH_DIRECT_DECODE();
}
DECODE(OP_ZoneChange)
{
DECODE_LENGTH_EXACT(structs::ZoneChange_Struct);
@@ -4983,7 +5050,7 @@ namespace RoF
//sprintf(hdr.unknown000, "06e0002Y1W00");
snprintf(hdr.unknown000, sizeof(hdr.unknown000), "%012d", item->ID);
snprintf(hdr.unknown000, sizeof(hdr.unknown000), "%016d", item->ID);
hdr.stacksize = stackable ? charges : 1;
hdr.unknown004 = 0;
@@ -5054,7 +5121,7 @@ namespace RoF
hdrf.ItemClass = item->ItemClass;
ss.write((const char*)&hdrf, sizeof(RoF::structs::ItemSerializationHeaderFinish));
if (strlen(item->Name) > 0)
{
ss.write(item->Name, strlen(item->Name));
+418 -219
View File
File diff suppressed because it is too large Load Diff
+6 -3
View File
@@ -103,6 +103,8 @@ namespace RoF2 {
}
namespace consts {
static const size_t CHARACTER_CREATION_LIMIT = 12;
static const uint16 MAP_POSSESSIONS_SIZE = slots::_MainCount;
static const uint16 MAP_BANK_SIZE = 24;
static const uint16 MAP_SHARED_BANK_SIZE = 2;
@@ -178,9 +180,10 @@ namespace RoF2 {
static const uint16 ITEM_COMMON_SIZE = 6;
static const uint16 ITEM_CONTAINER_SIZE = 255; // 255; (server max will be 255..unsure what actual client is - test)
static const uint32 BANDOLIERS_COUNT = 20; // count = number of bandolier instances
static const uint32 BANDOLIER_SIZE = 4; // size = number of equipment slots in bandolier instance
static const uint32 POTION_BELT_SIZE = 5;
static const size_t BANDOLIERS_SIZE = 20; // number of bandolier instances
static const size_t BANDOLIER_ITEM_COUNT = 4; // number of equipment slots in bandolier instance
static const size_t POTION_BELT_ITEM_COUNT = 5;
static const size_t TEXT_LINK_BODY_LENGTH = 56;
}
+7
View File
@@ -2,10 +2,14 @@
// Begin RoF2 Encodes
E(OP_SendMembershipDetails)
E(OP_TraderShop)
E(OP_TraderDelItem)
// incoming packets that require a DECODE translation:
// Begin RoF2 Decodes
D(OP_TraderShop)
// End RoF2 Encodes/Decodes
// These require Encodes/Decodes for RoF, so they do for RoF2 as well
@@ -107,6 +111,7 @@ E(OP_Trader)
E(OP_TraderBuy)
E(OP_TributeInfo)
E(OP_TributeItem)
E(OP_VetClaimReply)
E(OP_VetRewardsAvaliable)
E(OP_WearChange)
E(OP_WhoAllResponse)
@@ -119,6 +124,7 @@ E(OP_ZoneSpawns)
D(OP_AdventureMerchantSell)
D(OP_AltCurrencySell)
D(OP_AltCurrencySellSelection)
D(OP_Animation)
D(OP_ApplyPoison)
D(OP_AugmentInfo)
D(OP_AugmentItem)
@@ -170,6 +176,7 @@ D(OP_Trader)
D(OP_TraderBuy)
D(OP_TradeSkillCombine)
D(OP_TributeItem)
D(OP_VetClaimRequest)
D(OP_WhoAllRequest)
D(OP_ZoneChange)
D(OP_ZoneEntry)
+247 -178
View File
@@ -97,11 +97,6 @@ static const uint32 MAX_PLAYER_TRIBUTES = 5;
static const uint32 MAX_TRIBUTE_TIERS = 10;
static const uint32 TRIBUTE_NONE = 0xFFFFFFFF;
static const uint32 MAX_PLAYER_BANDOLIER = 20;
static const uint32 MAX_PLAYER_BANDOLIER_ITEMS = 4;
static const uint32 MAX_POTIONS_IN_BELT = 5;
static const uint32 MAX_GROUP_LEADERSHIP_AA_ARRAY = 16;
static const uint32 MAX_RAID_LEADERSHIP_AA_ARRAY = 16;
static const uint32 MAX_LEADERSHIP_AA_ARRAY = (MAX_GROUP_LEADERSHIP_AA_ARRAY+MAX_RAID_LEADERSHIP_AA_ARRAY);
@@ -114,7 +109,7 @@ static const uint32 MAX_PP_SPELLBOOK = 720; // was 480
static const uint32 MAX_PP_MEMSPELL = 16; // was 12
static const uint32 MAX_PP_SKILL = PACKET_SKILL_ARRAY_SIZE; // 100 - actual skills buffer size
static const uint32 MAX_PP_AA_ARRAY = 300;
static const uint32 MAX_PP_DISCIPLINES = 200; // was 100
static const uint32 MAX_PP_DISCIPLINES = 300; // was 200
static const uint32 MAX_GROUP_MEMBERS = 6;
static const uint32 MAX_RECAST_TYPES = 20;
@@ -147,84 +142,87 @@ struct AdventureInfo {
*/
struct Color_Struct
{
union
{
struct
{
uint8 blue;
uint8 green;
uint8 red;
uint8 use_tint; // if there's a tint this is FF
} rgb;
uint32 color;
union {
struct {
uint8 Blue;
uint8 Green;
uint8 Red;
uint8 UseTint; // if there's a tint this is FF
} RGB;
uint32 Color;
};
};
/*
* 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 CharSelectEquip
{
uint32 Material;
uint32 Unknown1;
uint32 EliteMaterial;
uint32 HeroForgeModel;
uint32 Material2;
Color_Struct Color;
};
struct CharSelectEquip {
uint32 material;
uint32 unknown1;
uint32 elitematerial;
uint32 heroforgemodel;
uint32 material2;
Color_Struct color;
};
struct CharacterSelectEntry_Struct {
/*0000*/ char name[1]; // Name null terminated
/*0000*/ uint8 class_;
/*0000*/ uint32 race;
/*0000*/ uint8 level;
/*0000*/ uint8 class_2;
/*0000*/ uint32 race2;
/*0000*/ uint16 zone;
/*0000*/ uint16 instance;
/*0000*/ uint8 gender;
/*0000*/ uint8 face;
/*0000*/ CharSelectEquip equip[9];
/*0000*/ uint8 u15; // Seen FF
/*0000*/ uint8 u19; // Seen FF
/*0000*/ uint32 drakkin_tattoo;
/*0000*/ uint32 drakkin_details;
/*0000*/ uint32 deity;
/*0000*/ uint32 primary;
/*0000*/ uint32 secondary;
/*0000*/ uint8 haircolor;
/*0000*/ uint8 beardcolor;
/*0000*/ uint8 eyecolor1;
/*0000*/ uint8 eyecolor2;
/*0000*/ uint8 hairstyle;
/*0000*/ uint8 beard;
/*0000*/ uint8 char_enabled;
/*0000*/ uint8 tutorial; // Seen 1 for new char or 0 for existing
/*0000*/ uint32 drakkin_heritage;
/*0000*/ uint8 unknown1; // Seen 0
/*0000*/ uint8 gohome; // Seen 0 for new char and 1 for existing
struct CharacterSelectEntry_Struct
{
/*0000*/ char Name[1]; // Name null terminated
/*0000*/ uint8 Class;
/*0000*/ uint32 Race;
/*0000*/ uint8 Level;
/*0000*/ uint8 ShroudClass;
/*0000*/ uint32 ShroudRace;
/*0000*/ uint16 Zone;
/*0000*/ uint16 Instance;
/*0000*/ uint8 Gender;
/*0000*/ uint8 Face;
/*0000*/ CharSelectEquip Equip[9];
/*0000*/ uint8 Unknown15; // Seen FF
/*0000*/ uint8 Unknown19; // Seen FF
/*0000*/ uint32 DrakkinTattoo;
/*0000*/ uint32 DrakkinDetails;
/*0000*/ uint32 Deity;
/*0000*/ uint32 PrimaryIDFile;
/*0000*/ uint32 SecondaryIDFile;
/*0000*/ uint8 HairColor;
/*0000*/ uint8 BeardColor;
/*0000*/ uint8 EyeColor1;
/*0000*/ uint8 EyeColor2;
/*0000*/ uint8 HairStyle;
/*0000*/ uint8 Beard;
/*0000*/ uint8 GoHome; // Seen 0 for new char and 1 for existing
/*0000*/ uint8 Tutorial; // Seen 1 for new char or 0 for existing
/*0000*/ uint32 DrakkinHeritage;
/*0000*/ uint8 Unknown1; // Seen 0
/*0000*/ uint8 Enabled; // Swapped position with 'GoHome' 02/23/2015
/*0000*/ uint32 LastLogin;
/*0000*/ uint8 unknown2; // Seen 0
/*0000*/ uint8 Unknown2; // Seen 0
};
/*
** Character Selection Struct
**
*/
struct CharacterSelect_Struct {
/*000*/ uint32 char_count; //number of chars in this packet
/*004*/ CharacterSelectEntry_Struct entries[0];
struct CharacterSelect_Struct
{
/*000*/ uint32 CharCount; //number of chars in this packet
/*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
@@ -418,7 +416,7 @@ struct Spawn_Struct
/*0000*/ uint8 unknown12;
/*0000*/ uint32 petOwnerId;
/*0000*/ uint8 unknown13;
/*0000*/ uint32 unknown14; // Stance 64 = normal 4 = aggressive 40 = stun/mezzed
/*0000*/ uint32 PlayerState; // Stance 64 = normal 4 = aggressive 40 = stun/mezzed
/*0000*/ uint32 unknown15;
/*0000*/ uint32 unknown16;
/*0000*/ uint32 unknown17;
@@ -660,7 +658,10 @@ struct CastSpell_Struct
/*04*/ uint32 spell_id;
/*08*/ ItemSlotStruct inventoryslot; // slot for clicky item, Seen unknown of 131 = normal cast
/*20*/ uint32 target_id;
/*24*/ uint32 cs_unknown[5];
/*24*/ uint32 cs_unknown[2];
/*32*/ float y_pos;
/*36*/ float x_pos;
/*40*/ float z_pos;
/*44*/
};
@@ -686,7 +687,7 @@ struct SpellBuff_Struct
/*005*/ uint32 player_id; // 'global' ID of the caster, for wearoff messages
/*009*/ uint32 unknown016;
/*013*/ uint8 bard_modifier;
/*014*/ uint32 duration;
/*014*/ int32 duration;
/*018*/ uint8 level;
/*019*/ uint32 spellid;
/*023*/ uint32 counters;
@@ -702,7 +703,7 @@ struct SpellBuff_Struct_Old
/*003*/ uint8 effect; // not real
/*004*/ float unknown004; // Seen 1 for no buff
/*008*/ uint32 spellid;
/*012*/ uint32 duration;
/*012*/ int32 duration;
/*016*/ uint32 unknown016;
/*020*/ uint32 player_id; // 'global' ID of the caster, for wearoff messages
/*024*/ uint32 counters;
@@ -719,7 +720,7 @@ struct SpellBuffFade_Struct_Live {
/*007*/ uint8 unknown007;
/*008*/ float unknown008;
/*012*/ uint32 spellid;
/*016*/ uint32 duration;
/*016*/ int32 duration;
/*020*/ uint32 playerId; // Global player ID?
/*024*/ uint32 num_hits;
/*028*/ uint8 unknown0028[64];
@@ -735,7 +736,7 @@ struct SpellBuffFade_Struct {
/*006*/ uint8 effect;
/*007*/ uint8 unknown7;
/*008*/ uint32 spellid;
/*012*/ uint32 duration;
/*012*/ int32 duration;
/*016*/ uint32 num_hits;
/*020*/ uint32 unknown020; // Global player ID?
/*024*/ uint32 playerId; // Player id who cast the buff
@@ -876,7 +877,7 @@ struct AA_Array
{
uint32 AA;
uint32 value;
uint32 unknown08; // Looks like AA_Array is now 12 bytes in Live
uint32 charges; // expendable charges
};
struct Disciplines_Struct {
@@ -896,38 +897,66 @@ struct Tribute_Struct {
uint32 tier;
};
struct BandolierItem_Struct {
char item_name[1]; // Variable Length
uint32 item_id;
uint32 icon;
};
//len = 72
struct BandolierItem_Struct_Old {
uint32 item_id;
uint32 icon;
char item_name[64];
};
//len = 320
enum { //bandolier item positions
bandolierMainHand = 0,
bandolierOffHand,
// Bandolier item positions
enum
{
bandolierPrimary = 0,
bandolierSecondary,
bandolierRange,
bandolierAmmo
};
struct Bandolier_Struct {
char name[1]; // Variable Length
BandolierItem_Struct items[MAX_PLAYER_BANDOLIER_ITEMS];
struct BandolierItem_Struct
{
char Name[1]; // Variable Length
uint32 ID;
uint32 Icon;
};
struct Bandolier_Struct_Old {
char name[32];
BandolierItem_Struct items[MAX_PLAYER_BANDOLIER_ITEMS];
//len = 72
struct BandolierItem_Struct_Old
{
uint32 ID;
uint32 Icon;
char Name[64];
};
struct PotionBelt_Struct {
BandolierItem_Struct items[MAX_POTIONS_IN_BELT];
//len = 320
struct Bandolier_Struct
{
char Name[1]; // Variable Length
BandolierItem_Struct Items[consts::BANDOLIER_ITEM_COUNT];
};
struct Bandolier_Struct_Old
{
char Name[32];
BandolierItem_Struct Items[consts::BANDOLIER_ITEM_COUNT];
};
struct PotionBeltItem_Struct
{
char Name[1]; // Variable Length
uint32 ID;
uint32 Icon;
};
//len = 72
struct PotionBeltItem_Struct_Old
{
uint32 ID;
uint32 Icon;
char Name[64];
};
struct PotionBelt_Struct
{
PotionBeltItem_Struct Items[consts::POTION_BELT_ITEM_COUNT];
};
struct PotionBelt_Struct_Old
{
PotionBeltItem_Struct_Old Items[consts::POTION_BELT_ITEM_COUNT];
};
struct GroupLeadershipAA_Struct {
@@ -1137,7 +1166,7 @@ union
/*12949*/ uint32 aapoints; // Unspent AA points - Seen 1
/*12953*/ uint16 unknown_rof20; //
/*12955*/ uint32 bandolier_count; // Seen 20
/*12959*/ Bandolier_Struct bandoliers[MAX_PLAYER_BANDOLIER]; // [20] 740 bytes (Variable Name Sizes) - bandolier contents
/*12959*/ Bandolier_Struct bandoliers[consts::BANDOLIERS_SIZE]; // [20] 740 bytes (Variable Name Sizes) - bandolier contents
/*13699*/ uint32 potionbelt_count; // Seen 5
/*13703*/ PotionBelt_Struct potionbelt; // [5] 45 bytes potion belt - (Variable Name Sizes)
/*13748*/ int32 unknown_rof21; // Seen -1
@@ -1264,7 +1293,7 @@ struct TargetReject_Struct {
struct PetCommand_Struct {
/*00*/ uint32 command;
/*04*/ uint32 unknown04;
/*04*/ uint32 target;
/*08*/ uint32 unknown08;
};
@@ -1389,8 +1418,8 @@ struct RequestClientZoneChange_Struct {
struct Animation_Struct {
/*00*/ uint16 spawnid;
/*02*/ uint8 value;
/*03*/ uint8 action;
/*02*/ uint8 action;
/*03*/ uint8 speed;
/*04*/
};
@@ -1455,9 +1484,10 @@ struct CombatDamage_Struct
/* 04 */ uint8 type; //slashing, etc. 231 (0xE7) for spells
/* 05 */ uint32 spellid;
/* 09 */ int32 damage;
/* 13 */ float unknown11; // cd cc cc 3d
/* 17 */ float sequence; // see above notes in Action_Struct
/* 21 */ uint8 unknown19[9]; // was [9]
/* 13 */ float force; // cd cc cc 3d
/* 17 */ float meleepush_xy; // see above notes in Action_Struct
/* 21 */ float meleepush_z;
/* 25 */ uint8 unknown25[5]; // was [9]
/* 30 */
};
@@ -2443,7 +2473,7 @@ struct GroupFollow_Struct { // Live Follow Struct
struct InspectBuffs_Struct {
/*000*/ uint32 spell_id[BUFF_COUNT];
/*168*/ uint32 tics_remaining[BUFF_COUNT];
/*168*/ int32 tics_remaining[BUFF_COUNT];
};
struct LFG_Struct {
@@ -2914,10 +2944,12 @@ struct BazaarWindowStart_Struct {
struct BazaarWelcome_Struct {
BazaarWindowStart_Struct Beginning;
uint32 Traders;
uint32 Items;
uint8 Unknown012[8];
uint32 Code;
uint32 EntityID;
uint32 Traders;
uint32 Items;
uint32 Traders2;
uint32 Items2;
};
struct BazaarSearch_Struct {
@@ -3200,6 +3232,13 @@ struct BecomeTrader_Struct {
};
struct Trader_ShowItems_Struct {
/*000*/ uint32 Code;
/*004*/ uint16 TraderID;
/*008*/ uint32 Unknown08;
/*012*/
};
struct Trader_ShowItems_Struct_WIP {
/*000*/ uint32 Code;
/*004*/ char SerialNumber[17];
/*021*/ uint8 Unknown21;
@@ -3217,6 +3256,26 @@ struct TraderStatus_Struct {
};
struct TraderBuy_Struct {
/*000*/ uint32 Action;
/*004*/ uint32 Unknown004;
/*008*/ uint32 Unknown008;
/*012*/ uint32 Unknown012;
/*016*/ uint32 TraderID;
/*020*/ char BuyerName[64];
/*084*/ char SellerName[64];
/*148*/ char Unknown148[32];
/*180*/ char ItemName[64];
/*244*/ char SerialNumber[16];
/*260*/ uint32 Unknown076;
/*264*/ uint32 ItemID;
/*268*/ uint32 Price;
/*272*/ uint32 AlreadySold;
/*276*/ uint32 Unknown276;
/*280*/ uint32 Quantity;
/*284*/
};
struct TraderBuy_Struct_OLD {
/*000*/ uint32 Action;
/*004*/ uint32 Unknown004;
/*008*/ uint32 Price;
@@ -3246,25 +3305,19 @@ struct MoneyUpdate_Struct{
int32 copper;
};
//struct MoneyUpdate_Struct
//{
//*0000*/ uint32 spawn_id; // ***Placeholder
//*0004*/ uint32 cointype; // Coin Type
//*0008*/ uint32 amount; // Amount
//*0012*/
//};
struct TraderDelItem_Struct{
uint32 slotid;
uint32 quantity;
uint32 unknown;
/*000*/ uint32 Unknown000;
/*004*/ uint32 TraderID;
/*008*/ char SerialNumber[16];
/*024*/ uint32 Unknown012;
/*028*/
};
struct TraderClick_Struct{
uint32 traderid;
uint32 unknown4[2];
uint32 approval;
/*000*/ uint32 Code;
/*004*/ uint32 TraderID;
/*008*/ uint32 Approval;
/*012*/
};
struct FormattedMessage_Struct{
@@ -3567,7 +3620,7 @@ struct Split_Struct
*/
struct NewCombine_Struct {
/*00*/ ItemSlotStruct container_slot;
/*12*/ ItemSlotStruct guildtribute_slot; // Slot type is 8? (MapGuildTribute = 8 -U)
/*12*/ ItemSlotStruct guildtribute_slot; // Slot type is 8? (MapGuildTribute = 8)
/*24*/
};
@@ -4088,30 +4141,35 @@ struct DynamicWall_Struct {
/*80*/
};
enum { //bandolier actions
BandolierCreate = 0,
BandolierRemove = 1,
BandolierSet = 2
// Bandolier actions
enum
{
bandolierCreate = 0,
bandolierRemove,
bandolierSet
};
struct BandolierCreate_Struct {
/*00*/ uint32 action; //0 for create
/*04*/ uint8 number;
/*05*/ char name[32];
/*37*/ uint16 unknown37; //seen 0x93FD
/*39*/ uint8 unknown39; //0
struct BandolierCreate_Struct
{
/*00*/ uint32 Action; //0 for create
/*04*/ uint8 Number;
/*05*/ char Name[32];
/*37*/ uint16 Unknown37; //seen 0x93FD
/*39*/ uint8 Unknown39; //0
};
struct BandolierDelete_Struct {
/*00*/ uint32 action;
/*04*/ uint8 number;
/*05*/ uint8 unknown05[35];
struct BandolierDelete_Struct
{
/*00*/ uint32 Action;
/*04*/ uint8 Number;
/*05*/ uint8 Unknown05[35];
};
struct BandolierSet_Struct {
/*00*/ uint32 action;
/*04*/ uint8 number;
/*05*/ uint8 unknown05[35];
struct BandolierSet_Struct
{
/*00*/ uint32 Action;
/*04*/ uint8 Number;
/*05*/ uint8 Unknown05[35];
};
struct Arrow_Struct {
@@ -4132,9 +4190,11 @@ struct Arrow_Struct {
/*068*/ uint8 unknown068;
/*069*/ uint8 unknown069;
/*070*/ uint8 unknown070;
/*071*/ uint8 item_type;
/*072*/ uint8 skill;
/*073*/ uint8 unknown073[16];
/*071*/ uint8 unknown071;
/*072*/ uint8 unknown072;
/*073*/ uint8 skill;
/*074*/ uint8 item_type;
/*075*/ uint8 unknown075[14];
/*089*/ char model_name[27];
/*116*/
};
@@ -4193,9 +4253,9 @@ struct SendAA_Struct {
/*0025*/ uint32 cost;
/*0029*/ uint32 seq;
/*0033*/ uint32 current_level; //1s, MQ2 calls this AARankRequired
/*0037*/ uint32 unknown037; // Introduced during HoT
/*0037*/ uint32 prereq_skill_count; // mutliple prereqs at least 1, even no prereqs
/*0041*/ uint32 prereq_skill; //is < 0, abs() is category #
/*0045*/ uint32 unknown045; // New Mar 21 2012 - Seen 1
/*0045*/ uint32 prereq_minpoints_count; // mutliple prereqs at least 1, even no prereqs
/*0049*/ uint32 prereq_minpoints; //min points in the prereq
/*0053*/ uint32 type;
/*0057*/ uint32 spellid;
@@ -4208,10 +4268,16 @@ struct SendAA_Struct {
/*0081*/ uint32 last_id;
/*0085*/ uint32 next_id;
/*0089*/ uint32 cost2;
/*0093*/ uint8 unknown80[7];
/*0093*/ uint8 unknown93;
/*0094*/ uint8 grant_only; // VetAAs, progression, etc
/*0095*/ uint8 unknown95; // 1 for skill cap increase AAs, Mystical Attuning, and RNG attack inc, doesn't seem to matter though
/*0096*/ uint32 expendable_charges; // max charges of the AA
/*0100*/ uint32 aa_expansion;
/*0104*/ uint32 special_category;
/*0108*/ uint32 unknown0096;
/*0108*/ uint8 shroud;
/*0109*/ uint8 unknown109;
/*0110*/ uint8 layonhands; // 1 for lay on hands -- doesn't seem to matter?
/*0111*/ uint8 unknown111;
/*0112*/ uint32 total_abilities;
/*0116*/ AA_Ability abilities[0];
};
@@ -4228,12 +4294,6 @@ struct AA_Action {
/*16*/
};
struct AA_Skills { //this should be removed and changed to AA_Array
/*00*/ uint32 aa_skill; // Total AAs Spent
/*04*/ uint32 aa_value;
/*08*/ uint32 unknown08;
/*12*/
};
struct AAExpUpdate_Struct {
/*00*/ uint32 unknown00; //seems to be a value from AA_Action.ability
@@ -4253,14 +4313,7 @@ struct AltAdvStats_Struct {
};
struct PlayerAA_Struct { // Is this still used?
AA_Skills aa_list[MAX_PP_AA_ARRAY];
};
struct AA_Values {
/*00*/ uint32 aa_skill;
/*04*/ uint32 aa_value;
/*08*/ uint32 unknown08;
/*12*/
AA_Array aa_list[MAX_PP_AA_ARRAY];
};
struct AATable_Struct {
@@ -4270,7 +4323,7 @@ struct AATable_Struct {
/*12*/ uint32 aa_spent_archetype; // Seen 40
/*16*/ uint32 aa_spent_class; // Seen 103
/*20*/ uint32 aa_spent_special; // Seen 0
/*24*/ AA_Values aa_list[MAX_PP_AA_ARRAY];
/*24*/ AA_Array aa_list[MAX_PP_AA_ARRAY];
};
struct Weather_Struct {
@@ -4498,7 +4551,7 @@ struct ItemSecondaryBodyStruct
uint32 augtype;
// swapped augrestrict and augdistiller positions
// (this swap does show the proper augment restrictions in Item Information window now)
// unsure what the purpose of augdistiller is at this time -U 3/17/2014
// unsure what the purpose of augdistiller is at this time 3/17/2014
int32 augrestrict2; // New to December 10th 2012 client - Hidden Aug Restriction
uint32 augrestrict;
AugSlotStruct augslots[6];
@@ -4673,17 +4726,33 @@ struct AugmentInfo_Struct
struct VeteranRewardItem
{
/*000*/ uint32 item_id;
/*004*/ uint32 charges;
/*008*/ char item_name[64];
/*000*/ uint32 name_length;
/*004*/ //char item_name[0]; // THIS IS NOT NULL TERMED
/*???*/ uint32 item_id;
/*???*/ uint32 charges;
};
struct VeteranRewardEntry
{
/*000*/ uint32 claim_id; // guessed
/*004*/ uint32 avaliable_count;
/*008*/ uint32 claim_count;
/*012*/ char enabled;
/*013*/ //VeteranRewardItem items[0];
};
struct VeteranReward
{
/*000*/ uint32 claim_id;
/*004*/ uint32 number_available;
/*008*/ uint32 claim_count;
/*012*/ VeteranRewardItem items[8];
/*000*/ uint32 claim_count;
/*004*/ //VeteranRewardEntry entries[0];
};
struct VeteranClaim
{
/*000*/ char name[68]; //name + other data
/*068*/ uint32 claim_id;
/*072*/ uint32 unknown072;
/*076*/ uint32 action;
};
struct ExpeditionEntryHeader_Struct
+6 -3
View File
@@ -102,6 +102,8 @@ namespace RoF {
}
namespace consts {
static const size_t CHARACTER_CREATION_LIMIT = 12;
static const uint16 MAP_POSSESSIONS_SIZE = slots::_MainCount;
static const uint16 MAP_BANK_SIZE = 24;
static const uint16 MAP_SHARED_BANK_SIZE = 2;
@@ -177,9 +179,10 @@ namespace RoF {
static const uint16 ITEM_COMMON_SIZE = 6;
static const uint16 ITEM_CONTAINER_SIZE = 255; // 255; (server max will be 255..unsure what actual client is - test)
static const uint32 BANDOLIERS_COUNT = 20; // count = number of bandolier instances
static const uint32 BANDOLIER_SIZE = 4; // size = number of equipment slots in bandolier instance
static const uint32 POTION_BELT_SIZE = 5;
static const size_t BANDOLIERS_SIZE = 20; // number of bandolier instances
static const size_t BANDOLIER_ITEM_COUNT = 4; // number of equipment slots in bandolier instance
static const size_t POTION_BELT_ITEM_COUNT = 5;
static const size_t TEXT_LINK_BODY_LENGTH = 55;
}
+3
View File
@@ -96,6 +96,7 @@ E(OP_Trader)
E(OP_TraderBuy)
E(OP_TributeInfo)
E(OP_TributeItem)
E(OP_VetClaimReply)
E(OP_VetRewardsAvaliable)
E(OP_WearChange)
E(OP_WhoAllResponse)
@@ -108,6 +109,7 @@ E(OP_ZoneSpawns)
D(OP_AdventureMerchantSell)
D(OP_AltCurrencySell)
D(OP_AltCurrencySellSelection)
D(OP_Animation)
D(OP_ApplyPoison)
D(OP_AugmentInfo)
D(OP_AugmentItem)
@@ -159,6 +161,7 @@ D(OP_Trader)
D(OP_TraderBuy)
D(OP_TradeSkillCombine)
D(OP_TributeItem)
D(OP_VetClaimRequest)
D(OP_WhoAllRequest)
D(OP_ZoneChange)
D(OP_ZoneEntry)
+200 -158
View File
@@ -97,11 +97,6 @@ static const uint32 MAX_PLAYER_TRIBUTES = 5;
static const uint32 MAX_TRIBUTE_TIERS = 10;
static const uint32 TRIBUTE_NONE = 0xFFFFFFFF;
static const uint32 MAX_PLAYER_BANDOLIER = 20;
static const uint32 MAX_PLAYER_BANDOLIER_ITEMS = 4;
static const uint32 MAX_POTIONS_IN_BELT = 5;
static const uint32 MAX_GROUP_LEADERSHIP_AA_ARRAY = 16;
static const uint32 MAX_RAID_LEADERSHIP_AA_ARRAY = 16;
static const uint32 MAX_LEADERSHIP_AA_ARRAY = (MAX_GROUP_LEADERSHIP_AA_ARRAY+MAX_RAID_LEADERSHIP_AA_ARRAY);
@@ -147,71 +142,87 @@ struct AdventureInfo {
*/
struct Color_Struct
{
union
{
struct
{
uint8 blue;
uint8 green;
uint8 red;
uint8 use_tint; // if there's a tint this is FF
} rgb;
uint32 color;
union {
struct {
uint8 Blue;
uint8 Green;
uint8 Red;
uint8 UseTint; // if there's a tint this is FF
} RGB;
uint32 Color;
};
};
struct CharSelectEquip {
uint32 material;
uint32 unknown1;
uint32 elitematerial;
uint32 heroforgemodel;
uint32 material2;
Color_Struct color;
struct CharSelectEquip
{
uint32 Material;
uint32 Unknown1;
uint32 EliteMaterial;
uint32 HeroForgeModel;
uint32 Material2;
Color_Struct Color;
};
struct CharacterSelectEntry_Struct {
/*0000*/ char name[1]; // Name null terminated
/*0000*/ uint8 class_;
/*0000*/ uint32 race;
/*0000*/ uint8 level;
/*0000*/ uint8 class_2;
/*0000*/ uint32 race2;
/*0000*/ uint16 zone;
/*0000*/ uint16 instance;
/*0000*/ uint8 gender;
/*0000*/ uint8 face;
/*0000*/ CharSelectEquip equip[9];
/*0000*/ uint8 u15; // Seen FF
/*0000*/ uint8 u19; // Seen FF
/*0000*/ uint32 drakkin_tattoo;
/*0000*/ uint32 drakkin_details;
/*0000*/ uint32 deity;
/*0000*/ uint32 primary;
/*0000*/ uint32 secondary;
/*0000*/ uint8 haircolor;
/*0000*/ uint8 beardcolor;
/*0000*/ uint8 eyecolor1;
/*0000*/ uint8 eyecolor2;
/*0000*/ uint8 hairstyle;
/*0000*/ uint8 beard;
/*0000*/ uint8 char_enabled;
/*0000*/ uint8 tutorial; // Seen 1 for new char or 0 for existing
/*0000*/ uint32 drakkin_heritage;
/*0000*/ uint8 unknown1; // Seen 0
/*0000*/ uint8 gohome; // Seen 0 for new char and 1 for existing
struct CharacterSelectEntry_Struct
{
/*0000*/ char Name[1]; // Name null terminated
/*0000*/ uint8 Class;
/*0000*/ uint32 Race;
/*0000*/ uint8 Level;
/*0000*/ uint8 ShroudClass;
/*0000*/ uint32 ShroudRace;
/*0000*/ uint16 Zone;
/*0000*/ uint16 Instance;
/*0000*/ uint8 Gender;
/*0000*/ uint8 Face;
/*0000*/ CharSelectEquip Equip[9];
/*0000*/ uint8 Unknown15; // Seen FF
/*0000*/ uint8 Unknown19; // Seen FF
/*0000*/ uint32 DrakkinTattoo;
/*0000*/ uint32 DrakkinDetails;
/*0000*/ uint32 Deity;
/*0000*/ uint32 PrimaryIDFile;
/*0000*/ uint32 SecondaryIDFile;
/*0000*/ uint8 HairColor;
/*0000*/ uint8 BeardColor;
/*0000*/ uint8 EyeColor1;
/*0000*/ uint8 EyeColor2;
/*0000*/ uint8 HairStyle;
/*0000*/ uint8 Beard;
/*0000*/ uint8 GoHome; // Seen 0 for new char and 1 for existing
/*0000*/ uint8 Tutorial; // Seen 1 for new char or 0 for existing
/*0000*/ uint32 DrakkinHeritage;
/*0000*/ uint8 Unknown1; // Seen 0
/*0000*/ uint8 Enabled; // Swapped position with 'GoHome' 02/23/2015
/*0000*/ uint32 LastLogin;
/*0000*/ uint8 unknown2; // Seen 0
/*0000*/ uint8 Unknown2; // Seen 0
};
/*
** Character Selection Struct
**
*/
struct CharacterSelect_Struct {
/*000*/ uint32 char_count; //number of chars in this packet
/*004*/ CharacterSelectEntry_Struct entries[0];
struct CharacterSelect_Struct
{
/*000*/ uint32 CharCount; //number of chars in this packet
/*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
@@ -252,20 +263,6 @@ struct Membership_Struct
};
/*
* 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*/
};
/*
** Generic Spawn Struct
** Length: 897 Octets
@@ -413,7 +410,7 @@ struct Spawn_Struct
/*0000*/ uint8 unknown12;
/*0000*/ uint32 petOwnerId;
/*0000*/ uint8 unknown13;
/*0000*/ uint32 unknown14; // Stance 64 = normal 4 = aggressive 40 = stun/mezzed
/*0000*/ uint32 PlayerState; // Stance 64 = normal 4 = aggressive 40 = stun/mezzed
/*0000*/ uint32 unknown15;
/*0000*/ uint32 unknown16;
/*0000*/ uint32 unknown17;
@@ -650,7 +647,10 @@ struct CastSpell_Struct
/*04*/ uint32 spell_id;
/*08*/ ItemSlotStruct inventoryslot; // slot for clicky item, Seen unknown of 131 = normal cast
/*20*/ uint32 target_id;
/*24*/ uint32 cs_unknown[5];
/*24*/ uint32 cs_unknown[2];
/*32*/ float y_pos;
/*36*/ float x_pos;
/*40*/ float z_pos;
/*44*/
};
@@ -676,7 +676,7 @@ struct SpellBuff_Struct
/*005*/ uint32 player_id; // 'global' ID of the caster, for wearoff messages
/*009*/ uint32 unknown016;
/*013*/ uint8 bard_modifier;
/*014*/ uint32 duration;
/*014*/ int32 duration;
/*018*/ uint8 level;
/*019*/ uint32 spellid;
/*023*/ uint32 counters;
@@ -692,7 +692,7 @@ struct SpellBuff_Struct_Old
/*003*/ uint8 effect; // not real
/*004*/ float unknown004; // Seen 1 for no buff
/*008*/ uint32 spellid;
/*012*/ uint32 duration;
/*012*/ int32 duration;
/*016*/ uint32 unknown016;
/*020*/ uint32 player_id; // 'global' ID of the caster, for wearoff messages
/*024*/ uint32 counters;
@@ -709,7 +709,7 @@ struct SpellBuffFade_Struct_Live {
/*007*/ uint8 unknown007;
/*008*/ float unknown008;
/*012*/ uint32 spellid;
/*016*/ uint32 duration;
/*016*/ int32 duration;
/*020*/ uint32 playerId; // Global player ID?
/*024*/ uint32 num_hits;
/*028*/ uint8 unknown0028[64];
@@ -725,7 +725,7 @@ struct SpellBuffFade_Struct {
/*006*/ uint8 effect;
/*007*/ uint8 unknown7;
/*008*/ uint32 spellid;
/*012*/ uint32 duration;
/*012*/ int32 duration;
/*016*/ uint32 num_hits;
/*020*/ uint32 unknown020; // Global player ID?
/*024*/ uint32 playerId; // Player id who cast the buff
@@ -866,7 +866,7 @@ struct AA_Array
{
uint32 AA;
uint32 value;
uint32 unknown08; // Looks like AA_Array is now 12 bytes in Live
uint32 charges; // expendable charges
};
struct Disciplines_Struct {
@@ -880,38 +880,66 @@ struct Tribute_Struct {
uint32 tier;
};
struct BandolierItem_Struct {
char item_name[1]; // Variable Length
uint32 item_id;
uint32 icon;
};
//len = 72
struct BandolierItem_Struct_Old {
uint32 item_id;
uint32 icon;
char item_name[64];
};
//len = 320
enum { //bandolier item positions
bandolierMainHand = 0,
bandolierOffHand,
// Bandolier item positions
enum
{
bandolierPrimary = 0,
bandolierSecondary,
bandolierRange,
bandolierAmmo
};
struct Bandolier_Struct {
char name[1]; // Variable Length
BandolierItem_Struct items[MAX_PLAYER_BANDOLIER_ITEMS];
struct BandolierItem_Struct
{
char Name[1]; // Variable Length
uint32 ID;
uint32 Icon;
};
struct Bandolier_Struct_Old {
char name[32];
BandolierItem_Struct items[MAX_PLAYER_BANDOLIER_ITEMS];
//len = 72
struct BandolierItem_Struct_Old
{
uint32 ID;
uint32 Icon;
char Name[64];
};
struct PotionBelt_Struct {
BandolierItem_Struct items[MAX_POTIONS_IN_BELT];
//len = 320
struct Bandolier_Struct
{
char Name[1]; // Variable Length
BandolierItem_Struct Items[consts::BANDOLIER_ITEM_COUNT];
};
struct Bandolier_Struct_Old
{
char Name[32];
BandolierItem_Struct Items[consts::BANDOLIER_ITEM_COUNT];
};
struct PotionBeltItem_Struct
{
char Name[1]; // Variable Length
uint32 ID;
uint32 Icon;
};
//len = 72
struct PotionBeltItem_Struct_Old
{
uint32 ID;
uint32 Icon;
char Name[64];
};
struct PotionBelt_Struct
{
PotionBeltItem_Struct Items[consts::POTION_BELT_ITEM_COUNT];
};
struct PotionBelt_Struct_Old
{
PotionBeltItem_Struct_Old Items[consts::POTION_BELT_ITEM_COUNT];
};
struct GroupLeadershipAA_Struct {
@@ -1121,7 +1149,7 @@ union
/*12949*/ uint32 aapoints; // Unspent AA points - Seen 1
/*12953*/ uint16 unknown_rof20; //
/*12955*/ uint32 bandolier_count; // Seen 20
/*12959*/ Bandolier_Struct bandoliers[MAX_PLAYER_BANDOLIER]; // [20] 740 bytes (Variable Name Sizes) - bandolier contents
/*12959*/ Bandolier_Struct bandoliers[consts::BANDOLIERS_SIZE]; // [20] 740 bytes (Variable Name Sizes) - bandolier contents
/*13699*/ uint32 potionbelt_count; // Seen 5
/*13703*/ PotionBelt_Struct potionbelt; // [5] 45 bytes potion belt - (Variable Name Sizes)
/*13748*/ int32 unknown_rof21; // Seen -1
@@ -1295,7 +1323,7 @@ struct TargetReject_Struct {
struct PetCommand_Struct {
/*00*/ uint32 command;
/*04*/ uint32 unknown04;
/*04*/ uint32 target;
/*08*/ uint32 unknown08;
};
@@ -1420,8 +1448,8 @@ struct RequestClientZoneChange_Struct {
struct Animation_Struct {
/*00*/ uint16 spawnid;
/*02*/ uint8 value;
/*03*/ uint8 action;
/*02*/ uint8 action;
/*03*/ uint8 speed;
/*04*/
};
@@ -1486,9 +1514,10 @@ struct CombatDamage_Struct
/* 04 */ uint8 type; //slashing, etc. 231 (0xE7) for spells
/* 05 */ uint32 spellid;
/* 09 */ int32 damage;
/* 13 */ float unknown11; // cd cc cc 3d
/* 17 */ float sequence; // see above notes in Action_Struct
/* 21 */ uint8 unknown19[9]; // was [9]
/* 13 */ float force; // cd cc cc 3d
/* 17 */ float meleepush_xy; // see above notes in Action_Struct
/* 21 */ float meleepush_z;
/* 25 */ uint8 unknown25[5]; // was [9]
/* 30 */
};
@@ -2472,7 +2501,7 @@ struct GroupFollow_Struct { // Live Follow Struct
struct InspectBuffs_Struct {
/*000*/ uint32 spell_id[BUFF_COUNT];
/*168*/ uint32 tics_remaining[BUFF_COUNT];
/*168*/ int32 tics_remaining[BUFF_COUNT];
};
struct LFG_Struct {
@@ -3592,7 +3621,7 @@ struct Split_Struct
*/
struct NewCombine_Struct {
/*00*/ ItemSlotStruct container_slot;
/*12*/ ItemSlotStruct guildtribute_slot; // Slot type is 8? (MapGuildTribute = 8 -U)
/*12*/ ItemSlotStruct guildtribute_slot; // Slot type is 8? (MapGuildTribute = 8)
/*24*/
};
@@ -4113,30 +4142,35 @@ struct DynamicWall_Struct {
/*80*/
};
enum { //bandolier actions
BandolierCreate = 0,
BandolierRemove = 1,
BandolierSet = 2
// Bandolier actions
enum
{
bandolierCreate = 0,
bandolierRemove,
bandolierSet
};
struct BandolierCreate_Struct {
/*00*/ uint32 action; //0 for create
/*04*/ uint8 number;
/*05*/ char name[32];
/*37*/ uint16 unknown37; //seen 0x93FD
/*39*/ uint8 unknown39; //0
struct BandolierCreate_Struct
{
/*00*/ uint32 Action; //0 for create
/*04*/ uint8 Number;
/*05*/ char Name[32];
/*37*/ uint16 Unknown37; //seen 0x93FD
/*39*/ uint8 Unknown39; //0
};
struct BandolierDelete_Struct {
/*00*/ uint32 action;
/*04*/ uint8 number;
/*05*/ uint8 unknown05[35];
struct BandolierDelete_Struct
{
/*00*/ uint32 Action;
/*04*/ uint8 Number;
/*05*/ uint8 Unknown05[35];
};
struct BandolierSet_Struct {
/*00*/ uint32 action;
/*04*/ uint8 number;
/*05*/ uint8 unknown05[35];
struct BandolierSet_Struct
{
/*00*/ uint32 Action;
/*04*/ uint8 Number;
/*05*/ uint8 Unknown05[35];
};
struct Arrow_Struct {
@@ -4218,9 +4252,9 @@ struct SendAA_Struct {
/*0025*/ uint32 cost;
/*0029*/ uint32 seq;
/*0033*/ uint32 current_level; //1s, MQ2 calls this AARankRequired
/*0037*/ uint32 unknown037; // Introduced during HoT
/*0037*/ uint32 prereq_skill_count; // mutliple prereqs at least 1, even no prereqs
/*0041*/ uint32 prereq_skill; //is < 0, abs() is category #
/*0045*/ uint32 unknown045; // New Mar 21 2012 - Seen 1
/*0045*/ uint32 prereq_minpoints_count; // mutliple prereqs at least 1, even no prereqs
/*0049*/ uint32 prereq_minpoints; //min points in the prereq
/*0053*/ uint32 type;
/*0057*/ uint32 spellid;
@@ -4233,10 +4267,16 @@ struct SendAA_Struct {
/*0081*/ uint32 last_id;
/*0085*/ uint32 next_id;
/*0089*/ uint32 cost2;
/*0093*/ uint8 unknown80[7];
/*0093*/ uint8 unknown93;
/*0094*/ uint8 grant_only; // VetAAs, progression, etc
/*0095*/ uint8 unknown95; // 1 for skill cap increase AAs, Mystical Attuning, and RNG attack inc, doesn't seem to matter though
/*0096*/ uint32 expendable_charges; // max charges of the AA
/*0100*/ uint32 aa_expansion;
/*0104*/ uint32 special_category;
/*0108*/ uint32 unknown0096;
/*0108*/ uint8 shroud;
/*0109*/ uint8 unknown109;
/*0110*/ uint8 layonhands; // 1 for lay on hands -- doesn't seem to matter?
/*0111*/ uint8 unknown111;
/*0112*/ uint32 total_abilities;
/*0116*/ AA_Ability abilities[0];
};
@@ -4253,13 +4293,6 @@ struct AA_Action {
/*16*/
};
struct AA_Skills { //this should be removed and changed to AA_Array
/*00*/ uint32 aa_skill; // Total AAs Spent
/*04*/ uint32 aa_value;
/*08*/ uint32 unknown08;
/*12*/
};
struct AAExpUpdate_Struct {
/*00*/ uint32 unknown00; //seems to be a value from AA_Action.ability
/*04*/ uint32 aapoints_unspent;
@@ -4278,14 +4311,7 @@ struct AltAdvStats_Struct {
};
struct PlayerAA_Struct { // Is this still used?
AA_Skills aa_list[MAX_PP_AA_ARRAY];
};
struct AA_Values {
/*00*/ uint32 aa_skill;
/*04*/ uint32 aa_value;
/*08*/ uint32 unknown08;
/*12*/
AA_Array aa_list[MAX_PP_AA_ARRAY];
};
struct AATable_Struct {
@@ -4295,7 +4321,7 @@ struct AATable_Struct {
/*12*/ uint32 aa_spent_archetype; // Seen 40
/*16*/ uint32 aa_spent_class; // Seen 103
/*20*/ uint32 aa_spent_special; // Seen 0
/*24*/ AA_Values aa_list[MAX_PP_AA_ARRAY];
/*24*/ AA_Array aa_list[MAX_PP_AA_ARRAY];
};
struct Weather_Struct {
@@ -4378,7 +4404,7 @@ struct RoFSlotStruct
struct ItemSerializationHeader
{
/*000*/ char unknown000[13]; // New for HoT. Looks like a string.
/*000*/ char unknown000[17]; // New for HoT. Looks like a string.
/*017*/ uint32 stacksize;
/*021*/ uint32 unknown004;
/*025*/ uint8 slot_type; // 0 = normal, 1 = bank, 2 = shared bank, 9 = merchant, 20 = ?
@@ -4524,7 +4550,7 @@ struct ItemSecondaryBodyStruct
uint32 augtype;
// swapped augrestrict and augdistiller positions
// (this swap does show the proper augment restrictions in Item Information window now)
// unsure what the purpose of augdistiller is at this time -U 3/17/2014
// unsure what the purpose of augdistiller is at this time 3/17/2014
uint32 augdistiller; // New to December 10th 2012 client - NEW
uint32 augrestrict;
AugSlotStruct augslots[6];
@@ -4688,17 +4714,33 @@ struct AugmentInfo_Struct
struct VeteranRewardItem
{
/*000*/ uint32 item_id;
/*004*/ uint32 charges;
/*008*/ char item_name[64];
/*000*/ uint32 name_length;
/*004*/ //char item_name[0]; // THIS IS NOT NULL TERMED
/*???*/ uint32 item_id;
/*???*/ uint32 charges;
};
struct VeteranRewardEntry
{
/*000*/ uint32 claim_id; // guessed
/*004*/ uint32 avaliable_count;
/*008*/ uint32 claim_count;
/*012*/ char enabled;
/*013*/ //VeteranRewardItem items[0];
};
struct VeteranReward
{
/*000*/ uint32 claim_id;
/*004*/ uint32 number_available;
/*008*/ uint32 claim_count;
/*012*/ VeteranRewardItem items[8];
/*000*/ uint32 claim_count;
/*004*/ //VeteranRewardEntry entries[0];
};
struct VeteranClaim
{
/*000*/ char name[68]; //name + other data
/*068*/ uint32 claim_id;
/*072*/ uint32 unknown072;
/*076*/ uint32 action;
};
struct ExpeditionEntryHeader_Struct
+147 -122
View File
@@ -446,7 +446,9 @@ namespace SoD
OUT(type);
OUT(spellid);
OUT(damage);
eq->sequence = emu->sequence;
OUT(force)
OUT(meleepush_xy);
OUT(meleepush_z)
FINISH_ENCODE();
}
@@ -1542,13 +1544,13 @@ namespace SoD
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;
eq->equipment[r].Material = emu->item_material[r];
eq->equipment[r].Unknown1 = 0;
eq->equipment[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[r].Color);
}
// OUT(unknown00224[48]);
//NOTE: new client supports 300 AAs, our internal rep/PP
@@ -1556,6 +1558,7 @@ namespace SoD
for (r = 0; r < MAX_PP_AA_ARRAY; r++) {
OUT(aa_array[r].AA);
OUT(aa_array[r].value);
OUT(aa_array[r].charges);
}
// OUT(unknown02220[4]);
OUT(mana);
@@ -1606,26 +1609,46 @@ namespace SoD
OUT(endurance);
OUT(aapoints_spent);
OUT(aapoints);
// OUT(unknown06160[4]);
//NOTE: new client supports 20 bandoliers, our internal rep
//only supports 4..
for (r = 0; r < 4; r++) {
OUT_str(bandoliers[r].name);
uint32 k;
for (k = 0; k < structs::MAX_PLAYER_BANDOLIER_ITEMS; k++) {
OUT(bandoliers[r].items[k].item_id);
OUT(bandoliers[r].items[k].icon);
OUT_str(bandoliers[r].items[k].item_name);
// Copy bandoliers where server and client indexes converge
for (r = 0; r < EmuConstants::BANDOLIERS_SIZE && r < consts::BANDOLIERS_SIZE; ++r) {
OUT_str(bandoliers[r].Name);
for (uint32 k = 0; k < consts::BANDOLIER_ITEM_COUNT; ++k) { // Will need adjusting if 'server != client' is ever true
OUT(bandoliers[r].Items[k].ID);
OUT(bandoliers[r].Items[k].Icon);
OUT_str(bandoliers[r].Items[k].Name);
}
}
// OUT(unknown07444[5120]);
for (r = 0; r < structs::MAX_POTIONS_IN_BELT; r++) {
OUT(potionbelt.items[r].item_id);
OUT(potionbelt.items[r].icon);
OUT_str(potionbelt.items[r].item_name);
// Nullify bandoliers where server and client indexes diverge, with a client bias
for (r = EmuConstants::BANDOLIERS_SIZE; r < consts::BANDOLIERS_SIZE; ++r) {
eq->bandoliers[r].Name[0] = '\0';
for (uint32 k = 0; k < consts::BANDOLIER_ITEM_COUNT; ++k) { // Will need adjusting if 'server != client' is ever true
eq->bandoliers[r].Items[k].ID = 0;
eq->bandoliers[r].Items[k].Icon = 0;
eq->bandoliers[r].Items[k].Name[0] = '\0';
}
}
// OUT(unknown07444[5120]);
// Copy potion belt where server and client indexes converge
for (r = 0; r < EmuConstants::POTION_BELT_ITEM_COUNT && r < consts::POTION_BELT_ITEM_COUNT; ++r) {
OUT(potionbelt.Items[r].ID);
OUT(potionbelt.Items[r].Icon);
OUT_str(potionbelt.Items[r].Name);
}
// Nullify potion belt where server and client indexes diverge, with a client bias
for (r = EmuConstants::POTION_BELT_ITEM_COUNT; r < consts::POTION_BELT_ITEM_COUNT; ++r) {
eq->potionbelt.Items[r].ID = 0;
eq->potionbelt.Items[r].Icon = 0;
eq->potionbelt.Items[r].Name[0] = '\0';
}
// OUT(unknown12852[8]);
// OUT(unknown12864[76]);
OUT_str(name);
OUT_str(last_name);
OUT(guild_id);
@@ -1876,6 +1899,7 @@ namespace SoD
OUT(cost2);
eq->aa_expansion = emu->aa_expansion;
eq->special_category = emu->special_category;
eq->expendable_charges = emu->special_category == 7 ? 1 : 0; // temp hack, this can actually be any number
OUT(total_abilities);
unsigned int r;
for (r = 0; r < emu->total_abilities; r++) {
@@ -1891,76 +1915,96 @@ namespace SoD
ENCODE(OP_SendCharInfo)
{
ENCODE_LENGTH_EXACT(CharacterSelect_Struct);
ENCODE_LENGTH_ATLEAST(CharacterSelect_Struct);
SETUP_VAR_ENCODE(CharacterSelect_Struct);
//EQApplicationPacket *packet = *p;
//const CharacterSelect_Struct *emu = (CharacterSelect_Struct *) packet->pBuffer;
// Zero-character count shunt
if (emu->CharCount == 0) {
ALLOC_VAR_ENCODE(structs::CharacterSelect_Struct, sizeof(structs::CharacterSelect_Struct));
eq->CharCount = emu->CharCount;
eq->TotalChars = emu->TotalChars;
int char_count;
int namelen = 0;
for (char_count = 0; char_count < 10; char_count++) {
if (emu->name[char_count][0] == '\0')
break;
if (strcmp(emu->name[char_count], "<none>") == 0)
break;
namelen += strlen(emu->name[char_count]);
if (eq->TotalChars > consts::CHARACTER_CREATION_LIMIT)
eq->TotalChars = consts::CHARACTER_CREATION_LIMIT;
FINISH_ENCODE();
return;
}
int total_length = sizeof(structs::CharacterSelect_Struct)
+ char_count * sizeof(structs::CharacterSelectEntry_Struct)
+ namelen;
unsigned char *emu_ptr = __emu_buffer;
emu_ptr += sizeof(CharacterSelect_Struct);
CharacterSelectEntry_Struct *emu_cse = (CharacterSelectEntry_Struct *)nullptr;
size_t names_length = 0;
size_t character_count = 0;
for (; character_count < emu->CharCount && character_count < consts::CHARACTER_CREATION_LIMIT; ++character_count) {
emu_cse = (CharacterSelectEntry_Struct *)emu_ptr;
names_length += strlen(emu_cse->Name);
emu_ptr += sizeof(CharacterSelectEntry_Struct);
}
size_t total_length = sizeof(structs::CharacterSelect_Struct)
+ character_count * sizeof(structs::CharacterSelectEntry_Struct)
+ names_length;
ALLOC_VAR_ENCODE(structs::CharacterSelect_Struct, total_length);
structs::CharacterSelectEntry_Struct *eq_cse = (structs::CharacterSelectEntry_Struct *)nullptr;
//unsigned char *eq_buffer = new unsigned char[total_length];
//structs::CharacterSelect_Struct *eq_head = (structs::CharacterSelect_Struct *) eq_buffer;
eq->CharCount = character_count;
eq->TotalChars = emu->TotalChars;
eq->char_count = char_count;
eq->total_chars = 10;
if (eq->TotalChars > consts::CHARACTER_CREATION_LIMIT)
eq->TotalChars = consts::CHARACTER_CREATION_LIMIT;
unsigned char *bufptr = (unsigned char *)eq->entries;
int r;
for (r = 0; r < char_count; r++) {
{ //pre-name section...
structs::CharacterSelectEntry_Struct *eq2 = (structs::CharacterSelectEntry_Struct *) bufptr;
eq2->level = emu->level[r];
eq2->hairstyle = emu->hairstyle[r];
eq2->gender = emu->gender[r];
memcpy(eq2->name, emu->name[r], strlen(emu->name[r]) + 1);
emu_ptr = __emu_buffer;
emu_ptr += sizeof(CharacterSelect_Struct);
unsigned char *eq_ptr = __packet->pBuffer;
eq_ptr += sizeof(structs::CharacterSelect_Struct);
for (int counter = 0; counter < character_count; ++counter) {
emu_cse = (CharacterSelectEntry_Struct *)emu_ptr;
eq_cse = (structs::CharacterSelectEntry_Struct *)eq_ptr; // base address
eq_cse->Level = emu_cse->Level;
eq_cse->HairStyle = emu_cse->HairStyle;
eq_cse->Gender = emu_cse->Gender;
strcpy(eq_cse->Name, emu_cse->Name);
eq_ptr += strlen(emu_cse->Name);
eq_cse = (structs::CharacterSelectEntry_Struct *)eq_ptr; // offset address (base + name length offset)
eq_cse->Name[0] = '\0'; // (offset)eq_cse->Name[0] = (base)eq_cse->Name[strlen(emu_cse->Name)]
eq_cse->Beard = emu_cse->Beard;
eq_cse->HairColor = emu_cse->HairColor;
eq_cse->Face = emu_cse->Face;
for (int equip_index = 0; equip_index < _MaterialCount; 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;
}
//adjust for name.
bufptr += strlen(emu->name[r]);
{ //post-name section...
structs::CharacterSelectEntry_Struct *eq2 = (structs::CharacterSelectEntry_Struct *) bufptr;
eq2->beard = emu->beard[r];
eq2->haircolor = emu->haircolor[r];
eq2->face = emu->face[r];
int k;
for (k = 0; k < _MaterialCount; k++) {
eq2->equip[k].material = emu->equip[r][k].material;
eq2->equip[k].unknown1 = emu->equip[r][k].unknown1;
eq2->equip[k].elitematerial = emu->equip[r][k].elitematerial;
eq2->equip[k].color.color = emu->equip[r][k].color.color;
}
eq2->primary = emu->primary[r];
eq2->secondary = emu->secondary[r];
eq2->tutorial = emu->tutorial[r]; // was u15
eq2->u15 = 0xff;
eq2->deity = emu->deity[r];
eq2->zone = emu->zone[r];
eq2->u19 = 0xFF;
eq2->race = emu->race[r];
eq2->gohome = emu->gohome[r];
eq2->class_ = emu->class_[r];
eq2->eyecolor1 = emu->eyecolor1[r];
eq2->beardcolor = emu->beardcolor[r];
eq2->eyecolor2 = emu->eyecolor2[r];
eq2->drakkin_heritage = emu->drakkin_heritage[r];
eq2->drakkin_tattoo = emu->drakkin_tattoo[r];
eq2->drakkin_details = emu->drakkin_details[r];
}
bufptr += sizeof(structs::CharacterSelectEntry_Struct);
eq_cse->PrimaryIDFile = emu_cse->PrimaryIDFile;
eq_cse->SecondaryIDFile = emu_cse->SecondaryIDFile;
eq_cse->Tutorial = emu_cse->Tutorial;
eq_cse->Unknown15 = emu_cse->Unknown15;
eq_cse->Deity = emu_cse->Deity;
eq_cse->Zone = emu_cse->Zone;
eq_cse->Unknown19 = emu_cse->Unknown19;
eq_cse->Race = emu_cse->Race;
eq_cse->GoHome = emu_cse->GoHome;
eq_cse->Class = emu_cse->Class;
eq_cse->EyeColor1 = emu_cse->EyeColor1;
eq_cse->BeardColor = emu_cse->BeardColor;
eq_cse->EyeColor2 = emu_cse->EyeColor2;
eq_cse->DrakkinHeritage = emu_cse->DrakkinHeritage;
eq_cse->DrakkinTattoo = emu_cse->DrakkinTattoo;
eq_cse->DrakkinDetails = emu_cse->DrakkinDetails;
emu_ptr += sizeof(CharacterSelectEntry_Struct);
eq_ptr += sizeof(structs::CharacterSelectEntry_Struct);
}
FINISH_ENCODE();
@@ -2355,7 +2399,7 @@ namespace SoD
OUT(material);
OUT(unknown06);
OUT(elite_material);
OUT(color.color);
OUT(color.Color);
OUT(wear_slot_id);
FINISH_ENCODE();
@@ -2427,42 +2471,23 @@ namespace SoD
ENCODE(OP_ZonePlayerToBind)
{
ENCODE_LENGTH_ATLEAST(ZonePlayerToBind_Struct);
SETUP_VAR_ENCODE(ZonePlayerToBind_Struct);
ALLOC_LEN_ENCODE(sizeof(structs::ZonePlayerToBind_Struct) + strlen(emu->zone_name));
ZonePlayerToBind_Struct *zps = (ZonePlayerToBind_Struct*)(*p)->pBuffer;
__packet->SetWritePosition(0);
__packet->WriteUInt16(emu->bind_zone_id);
__packet->WriteUInt16(emu->bind_instance_id);
__packet->WriteFloat(emu->x);
__packet->WriteFloat(emu->y);
__packet->WriteFloat(emu->z);
__packet->WriteFloat(emu->heading);
__packet->WriteString(emu->zone_name);
__packet->WriteUInt8(1); // save items
__packet->WriteUInt32(0); // hp
__packet->WriteUInt32(0); // mana
__packet->WriteUInt32(0); // endurance
std::stringstream ss(std::stringstream::in | std::stringstream::out | std::stringstream::binary);
unsigned char *buffer1 = new unsigned char[sizeof(structs::ZonePlayerToBindHeader_Struct) + strlen(zps->zone_name)];
structs::ZonePlayerToBindHeader_Struct *zph = (structs::ZonePlayerToBindHeader_Struct*)buffer1;
unsigned char *buffer2 = new unsigned char[sizeof(structs::ZonePlayerToBindFooter_Struct)];
structs::ZonePlayerToBindFooter_Struct *zpf = (structs::ZonePlayerToBindFooter_Struct*)buffer2;
zph->x = zps->x;
zph->y = zps->y;
zph->z = zps->z;
zph->heading = zps->heading;
zph->bind_zone_id = zps->bind_zone_id;
zph->bind_instance_id = zps->bind_instance_id;
strcpy(zph->zone_name, zps->zone_name);
zpf->unknown021 = 1;
zpf->unknown022 = 0;
zpf->unknown023 = 0;
zpf->unknown024 = 0;
ss.write((const char*)buffer1, (sizeof(structs::ZonePlayerToBindHeader_Struct) + strlen(zps->zone_name)));
ss.write((const char*)buffer2, sizeof(structs::ZonePlayerToBindFooter_Struct));
delete[] buffer1;
delete[] buffer2;
delete[](*p)->pBuffer;
(*p)->pBuffer = new unsigned char[ss.str().size()];
(*p)->size = ss.str().size();
memcpy((*p)->pBuffer, ss.str().c_str(), ss.str().size());
dest->FastQueuePacket(&(*p));
FINISH_ENCODE();
}
ENCODE(OP_ZoneServerInfo)
@@ -2715,7 +2740,7 @@ namespace SoD
VARSTRUCT_ENCODE_TYPE(uint8, Buffer, 0); // unknown12
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, emu->petOwnerId);
VARSTRUCT_ENCODE_TYPE(uint8, Buffer, 0); // unknown13
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0); // unknown14 - Stance 64 = normal 4 = aggressive 40 = stun/mezzed
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, emu->PlayerState);
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0); // unknown15
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0); // unknown16
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0); // unknown17
@@ -2742,7 +2767,7 @@ namespace SoD
for (k = 0; k < 9; ++k)
{
{
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, emu->colors[k].color);
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, emu->colors[k].Color);
}
}
}
@@ -2752,11 +2777,11 @@ namespace SoD
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0);
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0);
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, emu->equipment[MaterialPrimary].material);
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, emu->equipment[MaterialPrimary].Material);
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0);
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0);
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, emu->equipment[MaterialSecondary].material);
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, emu->equipment[MaterialSecondary].Material);
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0);
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0);
}
@@ -2767,9 +2792,9 @@ namespace SoD
structs::EquipStruct *Equipment = (structs::EquipStruct *)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].Material = emu->equipment[k].Material;
Equipment[k].Unknown1 = emu->equipment[k].Unknown1;
Equipment[k].EliteMaterial = emu->equipment[k].EliteMaterial;
}
Buffer += (sizeof(structs::EquipStruct) * 9);
@@ -3329,7 +3354,7 @@ namespace SoD
default:
emu->command = eq->command;
}
OUT(unknown);
IN(target);
FINISH_DIRECT_DECODE();
}
@@ -3484,7 +3509,7 @@ namespace SoD
IN(material);
IN(unknown06);
IN(elite_material);
IN(color.color);
IN(color.Color);
IN(wear_slot_id);
emu->hero_forge_model = 0;
emu->unknown18 = 0;
+6 -3
View File
@@ -101,6 +101,8 @@ namespace SoD {
}
namespace consts {
static const size_t CHARACTER_CREATION_LIMIT = 12;
static const uint16 MAP_POSSESSIONS_SIZE = slots::_MainCount;
static const uint16 MAP_BANK_SIZE = 24;
static const uint16 MAP_SHARED_BANK_SIZE = 2;
@@ -174,9 +176,10 @@ namespace SoD {
static const uint16 ITEM_COMMON_SIZE = 5;
static const uint16 ITEM_CONTAINER_SIZE = 10;
static const uint32 BANDOLIERS_COUNT = 20; // count = number of bandolier instances
static const uint32 BANDOLIER_SIZE = 4; // size = number of equipment slots in bandolier instance
static const uint32 POTION_BELT_SIZE = 5;
static const size_t BANDOLIERS_SIZE = 20; // number of bandolier instances
static const size_t BANDOLIER_ITEM_COUNT = 4; // number of equipment slots in bandolier instance
static const size_t POTION_BELT_ITEM_COUNT = 5;
static const size_t TEXT_LINK_BODY_LENGTH = 50;
}
+132 -112
View File
@@ -103,54 +103,53 @@ struct AdventureInfo {
*/
struct Color_Struct
{
union
{
struct
{
uint8 blue;
uint8 green;
uint8 red;
uint8 use_tint; // if there's a tint this is FF
} rgb;
uint32 color;
union {
struct {
uint8 Blue;
uint8 Green;
uint8 Red;
uint8 UseTint; // if there's a tint this is FF
} RGB;
uint32 Color;
};
};
struct CharSelectEquip {
//totally guessed;
uint32 material;
uint32 unknown1;
uint32 elitematerial;
Color_Struct color;
struct CharSelectEquip
{
uint32 Material;
uint32 Unknown1;
uint32 EliteMaterial;
Color_Struct Color;
};
struct CharacterSelectEntry_Struct {
/*0000*/ uint8 level; //
/*0000*/ uint8 hairstyle; //
/*0002*/ uint8 gender; //
/*0003*/ char name[1]; //variable length, edi+0
/*0000*/ uint8 beard; //
/*0001*/ uint8 haircolor; //
/*0000*/ uint8 face; //
/*0000*/ CharSelectEquip equip[9];
/*0000*/ uint32 primary; //
/*0000*/ uint32 secondary; //
/*0000*/ uint8 u15; // 0xff
/*0000*/ uint32 deity; //
/*0000*/ uint16 zone; //
/*0000*/ uint16 instance;
/*0000*/ uint8 gohome; //
/*0000*/ uint8 u19; // 0xff
/*0000*/ uint32 race; //
/*0000*/ uint8 tutorial; //
/*0000*/ uint8 class_; //
/*0000*/ uint8 eyecolor1; //
/*0000*/ uint8 beardcolor; //
/*0000*/ uint8 eyecolor2; //
/*0000*/ uint32 drakkin_heritage; // Drakkin Heritage
/*0000*/ uint32 drakkin_tattoo; // Drakkin Tattoo
/*0000*/ uint32 drakkin_details; // Drakkin Details (Facial Spikes)
/*0000*/ uint8 unknown; // New field to SoD
struct CharacterSelectEntry_Struct
{
/*0000*/ uint8 Level; //
/*0000*/ uint8 HairStyle; //
/*0002*/ uint8 Gender; //
/*0003*/ char Name[1]; // variable length, edi+0
/*0000*/ uint8 Beard; //
/*0001*/ uint8 HairColor; //
/*0000*/ uint8 Face; //
/*0000*/ CharSelectEquip Equip[9];
/*0000*/ uint32 PrimaryIDFile; //
/*0000*/ uint32 SecondaryIDFile; //
/*0000*/ uint8 Unknown15; // 0xff
/*0000*/ uint32 Deity; //
/*0000*/ uint16 Zone; //
/*0000*/ uint16 Instance;
/*0000*/ uint8 GoHome; //
/*0000*/ uint8 Unknown19; // 0xff
/*0000*/ uint32 Race; //
/*0000*/ uint8 Tutorial; //
/*0000*/ uint8 Class; //
/*0000*/ uint8 EyeColor1; //
/*0000*/ uint8 BeardColor; //
/*0000*/ uint8 EyeColor2; //
/*0000*/ uint32 DrakkinHeritage; // Drakkin Heritage
/*0000*/ uint32 DrakkinTattoo; // Drakkin Tattoo
/*0000*/ uint32 DrakkinDetails; // Drakkin Details (Facial Spikes)
/*0000*/ uint8 Unknown; // New field to SoD
};
@@ -158,20 +157,22 @@ struct CharacterSelectEntry_Struct {
** Character Selection Struct
**
*/
struct CharacterSelect_Struct {
/*0000*/ uint32 char_count; //number of chars in this packet
/*0004*/ uint32 total_chars; //total number of chars allowed?
/*0008*/ CharacterSelectEntry_Struct entries[0];
struct CharacterSelect_Struct
{
/*0000*/ uint32 CharCount; //number of chars in this packet
/*0004*/ uint32 TotalChars; //total number of chars allowed?
/*0008*/ CharacterSelectEntry_Struct Entries[0];
};
/*
* Visible equiptment.
* Size: 12 Octets
*/
struct EquipStruct {
/*00*/ uint32 material;
/*04*/ uint32 unknown1;
/*08*/ uint32 elitematerial;
struct EquipStruct
{
/*00*/ uint32 Material;
/*04*/ uint32 Unknown1;
/*08*/ uint32 EliteMaterial;
/*12*/
};
@@ -285,7 +286,7 @@ struct Spawn_Struct
/*0000*/ uint8 unknown12;
/*0000*/ uint32 petOwnerId;
/*0000*/ uint8 unknown13;
/*0000*/ uint32 unknown14; // Stance 64 = normal 4 = aggressive 40 = stun/mezzed
/*0000*/ uint32 PlayerState; // Stance 64 = normal 4 = aggressive 40 = stun/mezzed
/*0000*/ uint32 unknown15;
/*0000*/ uint32 unknown16;
/*0000*/ uint32 unknown17;
@@ -546,7 +547,7 @@ struct SpellBuff_Struct
/*002*/ uint8 bard_modifier;
/*003*/ uint8 effect; //not real
/*004*/ uint32 spellid;
/*008*/ uint32 duration;
/*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
@@ -563,7 +564,7 @@ struct SpellBuffFade_Struct {
/*006*/ uint8 effect;
/*007*/ uint8 unknown7;
/*008*/ uint32 spellid;
/*012*/ uint32 duration;
/*012*/ int32 duration;
/*016*/ uint32 unknown016;
/*020*/ uint32 unknown020; //prolly global player ID
/*024*/ uint32 playerId; // Player id who cast the buff
@@ -665,7 +666,7 @@ struct AA_Array
{
uint32 AA;
uint32 value;
uint32 unknown08; // Looks like AA_Array is now 12 bytes in Live
uint32 charges; // expendable
};
@@ -676,9 +677,6 @@ struct Disciplines_Struct {
};
static const uint32 MAX_PLAYER_TRIBUTES = 5;
static const uint32 MAX_PLAYER_BANDOLIER = 20;
static const uint32 MAX_PLAYER_BANDOLIER_ITEMS = 4;
static const uint32 MAX_POTIONS_IN_BELT = 5;
static const uint32 TRIBUTE_NONE = 0xFFFFFFFF;
struct Tribute_Struct {
@@ -686,26 +684,42 @@ struct Tribute_Struct {
uint32 tier;
};
//len = 72
struct BandolierItem_Struct {
uint32 item_id;
uint32 icon;
char item_name[64];
};
//len = 320
enum { //bandolier item positions
bandolierMainHand = 0,
bandolierOffHand,
// Bandolier item positions
enum
{
bandolierPrimary = 0,
bandolierSecondary,
bandolierRange,
bandolierAmmo
};
struct Bandolier_Struct {
char name[32];
BandolierItem_Struct items[MAX_PLAYER_BANDOLIER_ITEMS];
//len = 72
struct BandolierItem_Struct
{
uint32 ID;
uint32 Icon;
char Name[64];
};
struct PotionBelt_Struct {
BandolierItem_Struct items[MAX_POTIONS_IN_BELT];
//len = 320
struct Bandolier_Struct
{
char Name[32];
BandolierItem_Struct Items[consts::BANDOLIER_ITEM_COUNT];
};
//len = 72
struct PotionBeltItem_Struct
{
uint32 ID;
uint32 Icon;
char Name[64];
};
//len = 288
struct PotionBelt_Struct
{
PotionBeltItem_Struct Items[consts::POTION_BELT_ITEM_COUNT];
};
static const uint32 MAX_GROUP_LEADERSHIP_AA_ARRAY = 16;
@@ -925,7 +939,7 @@ struct PlayerProfile_Struct
/*08288*/ uint32 aapoints_spent; // Number of spent AA points
/*08292*/ uint32 aapoints; // Unspent AA points
/*08296*/ uint8 unknown06160[4];
/*08300*/ Bandolier_Struct bandoliers[MAX_PLAYER_BANDOLIER]; // [6400] bandolier contents
/*08300*/ Bandolier_Struct bandoliers[consts::BANDOLIERS_SIZE]; // [6400] bandolier contents
/*14700*/ PotionBelt_Struct potionbelt; // [360] potion belt 72 extra octets by adding 1 more belt slot
/*15060*/ uint8 unknown12852[8];
/*15068*/ uint32 available_slots;
@@ -1077,7 +1091,7 @@ struct TargetReject_Struct {
struct PetCommand_Struct {
/*000*/ uint32 command;
/*004*/ uint32 unknown;
/*004*/ uint32 target;
};
/*
@@ -1191,8 +1205,8 @@ struct RequestClientZoneChange_Struct {
struct Animation_Struct {
/*00*/ uint16 spawnid;
/*02*/ uint8 action;
/*03*/ uint8 value;
/*02*/ uint8 speed;
/*03*/ uint8 action;
/*04*/
};
@@ -1258,9 +1272,10 @@ struct CombatDamage_Struct
/* 04 */ uint8 type; //slashing, etc. 231 (0xE7) for spells
/* 05 */ uint16 spellid;
/* 07 */ int32 damage;
/* 11 */ float unknown11; // cd cc cc 3d
/* 15 */ float sequence; // see above notes in Action_Struct
/* 19 */ uint8 unknown19[9]; // was [9]
/* 11 */ float force; // cd cc cc 3d
/* 15 */ float meleepush_xy; // see above notes in Action_Struct
/* 19 */ float meleepush_z;
/* 23 */ uint8 unknown23[5]; // was [9]
/* 28 */
};
@@ -2357,7 +2372,7 @@ struct BookRequest_Struct {
**
*/
struct Object_Struct {
/*00*/ uint32 linked_list_addr[2];// <Zaphod> They are, get this, prev and next, ala linked list
/*00*/ uint32 linked_list_addr[2];// They are, get this, prev and next, ala linked list
/*08*/ uint32 unknown008; // Something related to the linked list?
/*12*/ uint32 drop_id; // Unique object id for zone
/*16*/ uint16 zone_id; // Redudant, but: Zone the object appears in
@@ -2377,8 +2392,8 @@ struct Object_Struct {
/*100*/ uint32 spawn_id; // Spawn Id of client interacting with object
/*104*/
};
//<Zaphod> 01 = generic drop, 02 = armor, 19 = weapon
//[13:40] <Zaphod> and 0xff seems to be indicative of the tradeskill/openable items that end up returning the old style item type in the OP_OpenObject
//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
/*
** Click Object Struct
@@ -3686,30 +3701,35 @@ struct DynamicWall_Struct {
/*80*/
};
enum { //bandolier actions
BandolierCreate = 0,
BandolierRemove = 1,
BandolierSet = 2
// Bandolier actions
enum
{
bandolierCreate = 0,
bandolierRemove,
bandolierSet
};
struct BandolierCreate_Struct {
/*00*/ uint32 action; //0 for create
/*04*/ uint8 number;
/*05*/ char name[32];
/*37*/ uint16 unknown37; //seen 0x93FD
/*39*/ uint8 unknown39; //0
struct BandolierCreate_Struct
{
/*00*/ uint32 Action; //0 for create
/*04*/ uint8 Number;
/*05*/ char Name[32];
/*37*/ uint16 Unknown37; //seen 0x93FD
/*39*/ uint8 Unknown39; //0
};
struct BandolierDelete_Struct {
/*00*/ uint32 action;
/*04*/ uint8 number;
/*05*/ uint8 unknown05[35];
struct BandolierDelete_Struct
{
/*00*/ uint32 Action;
/*04*/ uint8 Number;
/*05*/ uint8 Unknown05[35];
};
struct BandolierSet_Struct {
/*00*/ uint32 action;
/*04*/ uint8 number;
/*05*/ uint8 unknown05[35];
struct BandolierSet_Struct
{
/*00*/ uint32 Action;
/*04*/ uint8 Number;
/*05*/ uint8 Unknown05[35];
};
struct Arrow_Struct {
@@ -3799,10 +3819,16 @@ struct SendAA_Struct {
/*0069*/ uint32 last_id;
/*0073*/ uint32 next_id;
/*0077*/ uint32 cost2;
/*0081*/ uint8 unknown80[7];
/*0081*/ uint8 unknown81;
/*0082*/ uint8 grant_only; // VetAAs, progression, etc
/*0083*/ uint8 unknown83; // 1 for skill cap increase AAs, Mystical Attuning, and RNG attack inc, doesn't seem to matter though
/*0084*/ uint32 expendable_charges; // max charges of the AA
/*0088*/ uint32 aa_expansion;
/*0092*/ uint32 special_category;
/*0096*/ uint32 unknown0096;
/*0096*/ uint8 shroud;
/*0097*/ uint8 unknown97;
/*0098*/ uint8 layonhands; // 1 for lay on hands -- doesn't seem to matter?
/*0099*/ uint8 unknown99;
/*0100*/ uint32 total_abilities;
/*0104*/ AA_Ability abilities[0];
};
@@ -3818,12 +3844,6 @@ struct AA_Action {
/*12*/ uint32 exp_value;
};
struct AA_Skills { //this should be removed and changed to AA_Array
/*00*/ uint32 aa_skill; // Total AAs Spent
/*04*/ uint32 aa_value;
/*08*/ uint32 unknown08;
};
struct AAExpUpdate_Struct {
/*00*/ uint32 unknown00; //seems to be a value from AA_Action.ability
/*04*/ uint32 aapoints_unspent;
@@ -3841,12 +3861,12 @@ struct AltAdvStats_Struct {
};
struct PlayerAA_Struct { // Is this still used?
AA_Skills aa_list[MAX_PP_AA_ARRAY];
AA_Array aa_list[MAX_PP_AA_ARRAY];
};
struct AATable_Struct {
/*00*/ int32 aa_spent; // Total AAs Spent
/*04*/ AA_Skills aa_list[MAX_PP_AA_ARRAY];
/*04*/ AA_Array aa_list[MAX_PP_AA_ARRAY];
};
struct Weather_Struct {
+146 -120
View File
@@ -426,7 +426,9 @@ namespace SoF
OUT(type);
OUT(spellid);
OUT(damage);
eq->sequence = emu->sequence;
OUT(force)
OUT(meleepush_xy);
OUT(meleepush_z)
FINISH_ENCODE();
}
@@ -1200,13 +1202,13 @@ namespace SoF
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;
eq->equipment[r].Material = emu->item_material[r];
eq->equipment[r].Unknown1 = 0;
eq->equipment[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[r].Color);
}
// OUT(unknown00224[48]);
//NOTE: new client supports 300 AAs, our internal rep/PP
@@ -1214,6 +1216,7 @@ namespace SoF
for (r = 0; r < MAX_PP_AA_ARRAY; r++) {
OUT(aa_array[r].AA);
OUT(aa_array[r].value);
OUT(aa_array[r].charges);
}
// OUT(unknown02220[4]);
OUT(mana);
@@ -1264,26 +1267,46 @@ namespace SoF
OUT(endurance);
OUT(aapoints_spent);
OUT(aapoints);
// OUT(unknown06160[4]);
//NOTE: new client supports 20 bandoliers, our internal rep
//only supports 4..
for (r = 0; r < 4; r++) {
OUT_str(bandoliers[r].name);
uint32 k;
for (k = 0; k < structs::MAX_PLAYER_BANDOLIER_ITEMS; k++) {
OUT(bandoliers[r].items[k].item_id);
OUT(bandoliers[r].items[k].icon);
OUT_str(bandoliers[r].items[k].item_name);
// Copy bandoliers where server and client indexes converge
for (r = 0; r < EmuConstants::BANDOLIERS_SIZE && r < consts::BANDOLIERS_SIZE; ++r) {
OUT_str(bandoliers[r].Name);
for (uint32 k = 0; k < consts::BANDOLIER_ITEM_COUNT; ++k) { // Will need adjusting if 'server != client' is ever true
OUT(bandoliers[r].Items[k].ID);
OUT(bandoliers[r].Items[k].Icon);
OUT_str(bandoliers[r].Items[k].Name);
}
}
// OUT(unknown07444[5120]);
for (r = 0; r < structs::MAX_POTIONS_IN_BELT; r++) {
OUT(potionbelt.items[r].item_id);
OUT(potionbelt.items[r].icon);
OUT_str(potionbelt.items[r].item_name);
// Nullify bandoliers where server and client indexes diverge, with a client bias
for (r = EmuConstants::BANDOLIERS_SIZE; r < consts::BANDOLIERS_SIZE; ++r) {
eq->bandoliers[r].Name[0] = '\0';
for (uint32 k = 0; k < consts::BANDOLIER_ITEM_COUNT; ++k) { // Will need adjusting if 'server != client' is ever true
eq->bandoliers[r].Items[k].ID = 0;
eq->bandoliers[r].Items[k].Icon = 0;
eq->bandoliers[r].Items[k].Name[0] = '\0';
}
}
// OUT(unknown07444[5120]);
// Copy potion belt where server and client indexes converge
for (r = 0; r < EmuConstants::POTION_BELT_ITEM_COUNT && r < consts::POTION_BELT_ITEM_COUNT; ++r) {
OUT(potionbelt.Items[r].ID);
OUT(potionbelt.Items[r].Icon);
OUT_str(potionbelt.Items[r].Name);
}
// Nullify potion belt where server and client indexes diverge, with a client bias
for (r = EmuConstants::POTION_BELT_ITEM_COUNT; r < consts::POTION_BELT_ITEM_COUNT; ++r) {
eq->potionbelt.Items[r].ID = 0;
eq->potionbelt.Items[r].Icon = 0;
eq->potionbelt.Items[r].Name[0] = '\0';
}
// OUT(unknown12852[8]);
// OUT(unknown12864[76]);
OUT_str(name);
OUT_str(last_name);
OUT(guild_id);
@@ -1535,6 +1558,7 @@ namespace SoF
OUT(cost2);
eq->aa_expansion = emu->aa_expansion;
eq->special_category = emu->special_category;
eq->expendable_charges = emu->special_category == 7 ? 1 : 0; // temp hack, this can actually be any number
OUT(total_abilities);
unsigned int r;
for (r = 0; r < emu->total_abilities; r++) {
@@ -1550,76 +1574,96 @@ namespace SoF
ENCODE(OP_SendCharInfo)
{
ENCODE_LENGTH_EXACT(CharacterSelect_Struct);
ENCODE_LENGTH_ATLEAST(CharacterSelect_Struct);
SETUP_VAR_ENCODE(CharacterSelect_Struct);
//EQApplicationPacket *packet = *p;
//const CharacterSelect_Struct *emu = (CharacterSelect_Struct *) packet->pBuffer;
// Zero-character count shunt
if (emu->CharCount == 0) {
ALLOC_VAR_ENCODE(structs::CharacterSelect_Struct, sizeof(structs::CharacterSelect_Struct));
eq->CharCount = emu->CharCount;
eq->TotalChars = emu->TotalChars;
int char_count;
int namelen = 0;
for (char_count = 0; char_count < 10; char_count++) {
if (emu->name[char_count][0] == '\0')
break;
if (strcmp(emu->name[char_count], "<none>") == 0)
break;
namelen += strlen(emu->name[char_count]);
if (eq->TotalChars > consts::CHARACTER_CREATION_LIMIT)
eq->TotalChars = consts::CHARACTER_CREATION_LIMIT;
FINISH_ENCODE();
return;
}
int total_length = sizeof(structs::CharacterSelect_Struct)
+ char_count * sizeof(structs::CharacterSelectEntry_Struct)
+ namelen;
unsigned char *emu_ptr = __emu_buffer;
emu_ptr += sizeof(CharacterSelect_Struct);
CharacterSelectEntry_Struct *emu_cse = (CharacterSelectEntry_Struct *)nullptr;
size_t names_length = 0;
size_t character_count = 0;
for (; character_count < emu->CharCount && character_count < consts::CHARACTER_CREATION_LIMIT; ++character_count) {
emu_cse = (CharacterSelectEntry_Struct *)emu_ptr;
names_length += strlen(emu_cse->Name);
emu_ptr += sizeof(CharacterSelectEntry_Struct);
}
size_t total_length = sizeof(structs::CharacterSelect_Struct)
+ character_count * sizeof(structs::CharacterSelectEntry_Struct)
+ names_length;
ALLOC_VAR_ENCODE(structs::CharacterSelect_Struct, total_length);
structs::CharacterSelectEntry_Struct *eq_cse = (structs::CharacterSelectEntry_Struct *)nullptr;
//unsigned char *eq_buffer = new unsigned char[total_length];
//structs::CharacterSelect_Struct *eq_head = (structs::CharacterSelect_Struct *) eq_buffer;
eq->CharCount = character_count;
eq->TotalChars = emu->TotalChars;
eq->char_count = char_count;
eq->total_chars = 10;
if (eq->TotalChars > consts::CHARACTER_CREATION_LIMIT)
eq->TotalChars = consts::CHARACTER_CREATION_LIMIT;
unsigned char *bufptr = (unsigned char *)eq->entries;
int r;
for (r = 0; r < char_count; r++) {
{ //pre-name section...
structs::CharacterSelectEntry_Struct *eq2 = (structs::CharacterSelectEntry_Struct *) bufptr;
eq2->level = emu->level[r];
eq2->hairstyle = emu->hairstyle[r];
eq2->gender = emu->gender[r];
memcpy(eq2->name, emu->name[r], strlen(emu->name[r]) + 1);
emu_ptr = __emu_buffer;
emu_ptr += sizeof(CharacterSelect_Struct);
unsigned char *eq_ptr = __packet->pBuffer;
eq_ptr += sizeof(structs::CharacterSelect_Struct);
for (int counter = 0; counter < character_count; ++counter) {
emu_cse = (CharacterSelectEntry_Struct *)emu_ptr;
eq_cse = (structs::CharacterSelectEntry_Struct *)eq_ptr; // base address
eq_cse->Level = emu_cse->Level;
eq_cse->HairStyle = emu_cse->HairStyle;
eq_cse->Gender = emu_cse->Gender;
strcpy(eq_cse->Name, emu_cse->Name);
eq_ptr += strlen(emu_cse->Name);
eq_cse = (structs::CharacterSelectEntry_Struct *)eq_ptr; // offset address (base + name length offset)
eq_cse->Name[0] = '\0'; // (offset)eq_cse->Name[0] = (base)eq_cse->Name[strlen(emu_cse->Name)]
eq_cse->Beard = emu_cse->Beard;
eq_cse->HairColor = emu_cse->HairColor;
eq_cse->Face = emu_cse->Face;
for (int equip_index = 0; equip_index < _MaterialCount; 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;
}
//adjust for name.
bufptr += strlen(emu->name[r]);
{ //post-name section...
structs::CharacterSelectEntry_Struct *eq2 = (structs::CharacterSelectEntry_Struct *) bufptr;
eq2->beard = emu->beard[r];
eq2->haircolor = emu->haircolor[r];
eq2->face = emu->face[r];
int k;
for (k = 0; k < _MaterialCount; k++) {
eq2->equip[k].material = emu->equip[r][k].material;
eq2->equip[k].unknown1 = emu->equip[r][k].unknown1;
eq2->equip[k].elitematerial = emu->equip[r][k].elitematerial;
eq2->equip[k].color.color = emu->equip[r][k].color.color;
}
eq2->primary = emu->primary[r];
eq2->secondary = emu->secondary[r];
eq2->tutorial = emu->tutorial[r]; // was u15
eq2->u15 = 0xff;
eq2->deity = emu->deity[r];
eq2->zone = emu->zone[r];
eq2->u19 = 0xFF;
eq2->race = emu->race[r];
eq2->gohome = emu->gohome[r];
eq2->class_ = emu->class_[r];
eq2->eyecolor1 = emu->eyecolor1[r];
eq2->beardcolor = emu->beardcolor[r];
eq2->eyecolor2 = emu->eyecolor2[r];
eq2->drakkin_heritage = emu->drakkin_heritage[r];
eq2->drakkin_tattoo = emu->drakkin_tattoo[r];
eq2->drakkin_details = emu->drakkin_details[r];
}
bufptr += sizeof(structs::CharacterSelectEntry_Struct);
eq_cse->PrimaryIDFile = emu_cse->PrimaryIDFile;
eq_cse->SecondaryIDFile = emu_cse->SecondaryIDFile;
eq_cse->Tutorial = emu_cse->Tutorial;
eq_cse->Unknown15 = emu_cse->Unknown15;
eq_cse->Deity = emu_cse->Deity;
eq_cse->Zone = emu_cse->Zone;
eq_cse->Unknown19 = emu_cse->Unknown19;
eq_cse->Race = emu_cse->Race;
eq_cse->GoHome = emu_cse->GoHome;
eq_cse->Class = emu_cse->Class;
eq_cse->EyeColor1 = emu_cse->EyeColor1;
eq_cse->BeardColor = emu_cse->BeardColor;
eq_cse->EyeColor2 = emu_cse->EyeColor2;
eq_cse->DrakkinHeritage = emu_cse->DrakkinHeritage;
eq_cse->DrakkinTattoo = emu_cse->DrakkinTattoo;
eq_cse->DrakkinDetails = emu_cse->DrakkinDetails;
emu_ptr += sizeof(CharacterSelectEntry_Struct);
eq_ptr += sizeof(structs::CharacterSelectEntry_Struct);
}
FINISH_ENCODE();
@@ -1941,7 +1985,7 @@ namespace SoF
OUT(material);
OUT(unknown06);
OUT(elite_material);
OUT(color.color);
OUT(color.Color);
OUT(wear_slot_id);
FINISH_ENCODE();
@@ -1951,42 +1995,23 @@ namespace SoF
ENCODE(OP_ZonePlayerToBind)
{
ENCODE_LENGTH_ATLEAST(ZonePlayerToBind_Struct);
SETUP_VAR_ENCODE(ZonePlayerToBind_Struct);
ALLOC_LEN_ENCODE(sizeof(structs::ZonePlayerToBind_Struct) + strlen(emu->zone_name));
ZonePlayerToBind_Struct *zps = (ZonePlayerToBind_Struct*)(*p)->pBuffer;
__packet->SetWritePosition(0);
__packet->WriteUInt16(emu->bind_zone_id);
__packet->WriteUInt16(emu->bind_instance_id);
__packet->WriteFloat(emu->x);
__packet->WriteFloat(emu->y);
__packet->WriteFloat(emu->z);
__packet->WriteFloat(emu->heading);
__packet->WriteString(emu->zone_name);
__packet->WriteUInt8(1); // save items
__packet->WriteUInt32(0); // hp
__packet->WriteUInt32(0); // mana
__packet->WriteUInt32(0); // endurance
std::stringstream ss(std::stringstream::in | std::stringstream::out | std::stringstream::binary);
unsigned char *buffer1 = new unsigned char[sizeof(structs::ZonePlayerToBindHeader_Struct) + strlen(zps->zone_name)];
structs::ZonePlayerToBindHeader_Struct *zph = (structs::ZonePlayerToBindHeader_Struct*)buffer1;
unsigned char *buffer2 = new unsigned char[sizeof(structs::ZonePlayerToBindFooter_Struct)];
structs::ZonePlayerToBindFooter_Struct *zpf = (structs::ZonePlayerToBindFooter_Struct*)buffer2;
zph->x = zps->x;
zph->y = zps->y;
zph->z = zps->z;
zph->heading = zps->heading;
zph->bind_zone_id = zps->bind_zone_id;
zph->bind_instance_id = zps->bind_instance_id;
strcpy(zph->zone_name, zps->zone_name);
zpf->unknown021 = 1;
zpf->unknown022 = 0;
zpf->unknown023 = 0;
zpf->unknown024 = 0;
ss.write((const char*)buffer1, (sizeof(structs::ZonePlayerToBindHeader_Struct) + strlen(zps->zone_name)));
ss.write((const char*)buffer2, sizeof(structs::ZonePlayerToBindFooter_Struct));
delete[] buffer1;
delete[] buffer2;
delete[](*p)->pBuffer;
(*p)->pBuffer = new unsigned char[ss.str().size()];
(*p)->size = ss.str().size();
memcpy((*p)->pBuffer, ss.str().c_str(), ss.str().size());
dest->FastQueuePacket(&(*p));
FINISH_ENCODE();
}
ENCODE(OP_ZoneServerInfo)
@@ -2044,10 +2069,10 @@ namespace SoF
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;
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;
}
eq->StandState = emu->StandState;
eq->guildID = emu->guildID;
@@ -2066,6 +2091,7 @@ namespace SoF
eq->runspeed = emu->runspeed;
eq->light = emu->light;
eq->level = emu->level;
eq->PlayerState = emu->PlayerState;
eq->lfg = emu->lfg;
eq->hairstyle = emu->hairstyle;
eq->haircolor = emu->haircolor;
@@ -2109,7 +2135,7 @@ namespace SoF
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;
eq->colors[k].Color = emu->colors[k].Color;
}
eq->anon = emu->anon;
eq->face = emu->face;
@@ -2667,7 +2693,7 @@ namespace SoF
default:
emu->command = eq->command;
}
OUT(unknown);
IN(target);
FINISH_DIRECT_DECODE();
}
@@ -2808,7 +2834,7 @@ namespace SoF
IN(material);
IN(unknown06);
IN(elite_material);
IN(color.color);
IN(color.Color);
IN(wear_slot_id);
emu->hero_forge_model = 0;
emu->unknown18 = 0;
+6 -3
View File
@@ -101,6 +101,8 @@ namespace SoF {
}
namespace consts {
static const size_t CHARACTER_CREATION_LIMIT = 12;
static const uint16 MAP_POSSESSIONS_SIZE = slots::_MainCount;
static const uint16 MAP_BANK_SIZE = 24;
static const uint16 MAP_SHARED_BANK_SIZE = 2;
@@ -174,9 +176,10 @@ namespace SoF {
static const uint16 ITEM_COMMON_SIZE = 5;
static const uint16 ITEM_CONTAINER_SIZE = 10;
static const uint32 BANDOLIERS_COUNT = 20; // count = number of bandolier instances
static const uint32 BANDOLIER_SIZE = 4; // size = number of equipment slots in bandolier instance
static const uint32 POTION_BELT_SIZE = 5;
static const size_t BANDOLIERS_SIZE = 20; // number of bandolier instances
static const size_t BANDOLIER_ITEM_COUNT = 4; // number of equipment slots in bandolier instance
static const size_t POTION_BELT_ITEM_COUNT = 5;
static const size_t TEXT_LINK_BODY_LENGTH = 50;
}
+130 -110
View File
@@ -103,72 +103,74 @@ struct AdventureInfo {
*/
struct Color_Struct
{
union
{
struct
{
uint8 blue;
uint8 green;
uint8 red;
uint8 use_tint; // if there's a tint this is FF
} rgb;
uint32 color;
union {
struct {
uint8 Blue;
uint8 Green;
uint8 Red;
uint8 UseTint; // if there's a tint this is FF
} RGB;
uint32 Color;
};
};
struct CharSelectEquip {
uint32 material;
uint32 unknown1;
uint32 elitematerial;
Color_Struct color;
struct CharSelectEquip
{
uint32 Material;
uint32 Unknown1;
uint32 EliteMaterial;
Color_Struct Color;
};
struct CharacterSelectEntry_Struct {
/*0000*/ uint8 level; //
/*0000*/ uint8 hairstyle; //
/*0002*/ uint8 gender; //
/*0003*/ char name[1]; //variable length, edi+0
/*0000*/ uint8 beard; //
/*0001*/ uint8 haircolor; //
/*0000*/ uint8 face; //
/*0000*/ CharSelectEquip equip[9];
/*0000*/ uint32 primary; //
/*0000*/ uint32 secondary; //
/*0000*/ uint8 u15; // 0xff
/*0000*/ uint32 deity; //
/*0000*/ uint16 zone; //
/*0000*/ uint16 instance;
/*0000*/ uint8 gohome; //
/*0000*/ uint8 u19; // 0xff
/*0000*/ uint32 race; //
/*0000*/ uint8 tutorial; //
/*0000*/ uint8 class_; //
/*0000*/ uint8 eyecolor1; //
/*0000*/ uint8 beardcolor; //
/*0000*/ uint8 eyecolor2; //
/*0000*/ uint32 drakkin_heritage; // Drakkin Heritage
/*0000*/ uint32 drakkin_tattoo; // Drakkin Tattoo
/*0000*/ uint32 drakkin_details; // Drakkin Details (Facial Spikes)
struct CharacterSelectEntry_Struct
{
/*0000*/ uint8 Level; //
/*0000*/ uint8 HairStyle; //
/*0002*/ uint8 Gender; //
/*0003*/ char Name[1]; // variable length, edi+0
/*0000*/ uint8 Beard; //
/*0001*/ uint8 HairColor; //
/*0000*/ uint8 Face; //
/*0000*/ CharSelectEquip Equip[9];
/*0000*/ uint32 PrimaryIDFile; //
/*0000*/ uint32 SecondaryIDFile; //
/*0000*/ uint8 Unknown15; // 0xff
/*0000*/ uint32 Deity; //
/*0000*/ uint16 Zone; //
/*0000*/ uint16 Instance;
/*0000*/ uint8 GoHome; //
/*0000*/ uint8 Unknown19; // 0xff
/*0000*/ uint32 Race; //
/*0000*/ uint8 Tutorial; //
/*0000*/ uint8 Class; //
/*0000*/ uint8 EyeColor1; //
/*0000*/ uint8 BeardColor; //
/*0000*/ uint8 EyeColor2; //
/*0000*/ uint32 DrakkinHeritage; // Drakkin Heritage
/*0000*/ uint32 DrakkinTattoo; // Drakkin Tattoo
/*0000*/ uint32 DrakkinDetails; // Drakkin Details (Facial Spikes)
};
/*
** Character Selection Struct
**
*/
struct CharacterSelect_Struct {
/*0000*/ uint32 char_count; //number of chars in this packet
/*0004*/ uint32 total_chars; //total number of chars allowed?
/*0008*/ CharacterSelectEntry_Struct entries[0];
struct CharacterSelect_Struct
{
/*0000*/ uint32 CharCount; //number of chars in this packet
/*0004*/ uint32 TotalChars; //total number of chars allowed?
/*0008*/ CharacterSelectEntry_Struct Entries[0];
};
/*
* Visible equiptment.
* Size: 12 Octets
*/
struct EquipStruct {
/*00*/ uint32 material;
/*04*/ uint32 unknown1;
/*08*/ uint32 elitematerial;
struct EquipStruct
{
/*00*/ uint32 Material;
/*04*/ uint32 Unknown1;
/*08*/ uint32 EliteMaterial;
/*12*/
};
@@ -239,7 +241,8 @@ struct Spawn_Struct {
/*0506*/ uint8 light; // Spawn's lightsource
/*0507*/ uint8 unknown0507[4];
/*0511*/ uint8 level; // Spawn Level
/*0512*/ uint8 unknown0512[16];
/*0512*/ uint32 PlayerState;
/*0516*/ uint8 unknown0516[12];
/*0528*/ uint8 lfg;
/*0529*/ uint8 unknown0529[4];
/*0533*/ uint8 hairstyle; // Sets the style of hair
@@ -523,7 +526,7 @@ struct SpellBuff_Struct
/*002*/ uint8 bard_modifier;
/*003*/ uint8 effect; //not real
/*004*/ uint32 spellid;
/*008*/ uint32 duration;
/*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
@@ -540,7 +543,7 @@ struct SpellBuffFade_Struct {
/*006*/ uint8 effect;
/*007*/ uint8 unknown7;
/*008*/ uint32 spellid;
/*012*/ uint32 duration;
/*012*/ int32 duration;
/*016*/ uint32 unknown016;
/*020*/ uint32 unknown020; //prolly global player ID
/*024*/ uint32 playerId; // Player id who cast the buff
@@ -642,7 +645,7 @@ struct AA_Array
{
uint32 AA;
uint32 value;
uint32 unknown08; // Looks like AA_Array is now 12 bytes in Live
uint32 charges; // expendable charges
};
@@ -653,9 +656,6 @@ struct Disciplines_Struct {
};
static const uint32 MAX_PLAYER_TRIBUTES = 5;
static const uint32 MAX_PLAYER_BANDOLIER = 20;
static const uint32 MAX_PLAYER_BANDOLIER_ITEMS = 4;
static const uint32 MAX_POTIONS_IN_BELT = 5;
static const uint32 TRIBUTE_NONE = 0xFFFFFFFF;
struct Tribute_Struct {
@@ -663,26 +663,42 @@ struct Tribute_Struct {
uint32 tier;
};
//len = 72
struct BandolierItem_Struct {
uint32 item_id;
uint32 icon;
char item_name[64];
};
//len = 320
enum { //bandolier item positions
bandolierMainHand = 0,
bandolierOffHand,
// Bandolier item positions
enum
{
bandolierPrimary = 0,
bandolierSecondary,
bandolierRange,
bandolierAmmo
};
struct Bandolier_Struct {
char name[32];
BandolierItem_Struct items[MAX_PLAYER_BANDOLIER_ITEMS];
//len = 72
struct BandolierItem_Struct
{
uint32 ID;
uint32 Icon;
char Name[64];
};
struct PotionBelt_Struct {
BandolierItem_Struct items[MAX_POTIONS_IN_BELT];
//len = 320
struct Bandolier_Struct
{
char Name[32];
BandolierItem_Struct Items[consts::BANDOLIER_ITEM_COUNT];
};
//len = 72
struct PotionBeltItem_Struct
{
uint32 ID;
uint32 Icon;
char Name[64];
};
//len = 288
struct PotionBelt_Struct
{
PotionBeltItem_Struct Items[consts::POTION_BELT_ITEM_COUNT];
};
static const uint32 MAX_GROUP_LEADERSHIP_AA_ARRAY = 16;
@@ -901,7 +917,7 @@ struct PlayerProfile_Struct //23576 Octets
/*08288*/ uint32 aapoints_spent; // Number of spent AA points
/*08292*/ uint32 aapoints; // Unspent AA points
/*08296*/ uint8 unknown06160[4];
/*08300*/ Bandolier_Struct bandoliers[MAX_PLAYER_BANDOLIER]; // [6400] bandolier contents
/*08300*/ Bandolier_Struct bandoliers[consts::BANDOLIERS_SIZE]; // [6400] bandolier contents
/*14700*/ PotionBelt_Struct potionbelt; // [360] potion belt 72 extra octets by adding 1 more belt slot
/*15060*/ uint8 unknown12852[8];
/*15068*/ uint32 available_slots;
@@ -1053,7 +1069,7 @@ struct TargetReject_Struct {
struct PetCommand_Struct {
/*000*/ uint32 command;
/*004*/ uint32 unknown;
/*004*/ uint32 target;
};
/*
@@ -1167,8 +1183,8 @@ struct RequestClientZoneChange_Struct {
struct Animation_Struct {
/*00*/ uint16 spawnid;
/*02*/ uint8 action;
/*03*/ uint8 value;
/*02*/ uint8 speed;
/*03*/ uint8 action;
/*04*/
};
@@ -1234,9 +1250,10 @@ struct CombatDamage_Struct
/* 04 */ uint8 type; //slashing, etc. 231 (0xE7) for spells
/* 05 */ uint16 spellid;
/* 07 */ int32 damage;
/* 11 */ float unknown11; // cd cc cc 3d
/* 15 */ float sequence; // see above notes in Action_Struct
/* 19 */ uint8 unknown19[9]; // was [9]
/* 11 */ float force; // cd cc cc 3d
/* 15 */ float meleepush_xy; // see above notes in Action_Struct
/* 19 */ float meleepush_z;
/* 23 */ uint8 unknown23[5]; // was [9]
/* 28 */
};
@@ -2290,7 +2307,7 @@ struct BookRequest_Struct {
**
*/
struct Object_Struct {
/*00*/ uint32 linked_list_addr[2];// <Zaphod> They are, get this, prev and next, ala linked list
/*00*/ uint32 linked_list_addr[2];// They are, get this, prev and next, ala linked list
/*08*/ uint32 unknown008; // Something related to the linked list?
/*12*/ uint32 drop_id; // Unique object id for zone
/*16*/ uint16 zone_id; // Redudant, but: Zone the object appears in
@@ -2310,8 +2327,8 @@ struct Object_Struct {
/*100*/ uint32 spawn_id; // Spawn Id of client interacting with object
/*104*/
};
//<Zaphod> 01 = generic drop, 02 = armor, 19 = weapon
//[13:40] <Zaphod> and 0xff seems to be indicative of the tradeskill/openable items that end up returning the old style item type in the OP_OpenObject
//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
/*
** Click Object Struct
@@ -3548,30 +3565,35 @@ struct DynamicWall_Struct {
/*80*/
};
enum { //bandolier actions
BandolierCreate = 0,
BandolierRemove = 1,
BandolierSet = 2
// Bandolier actions
enum
{
bandolierCreate = 0,
bandolierRemove,
bandolierSet
};
struct BandolierCreate_Struct {
/*00*/ uint32 action; //0 for create
/*04*/ uint8 number;
/*05*/ char name[32];
/*37*/ uint16 unknown37; //seen 0x93FD
/*39*/ uint8 unknown39; //0
struct BandolierCreate_Struct
{
/*00*/ uint32 Action; //0 for create
/*04*/ uint8 Number;
/*05*/ char Name[32];
/*37*/ uint16 Unknown37; //seen 0x93FD
/*39*/ uint8 Unknown39; //0
};
struct BandolierDelete_Struct {
/*00*/ uint32 action;
/*04*/ uint8 number;
/*05*/ uint8 unknown05[35];
struct BandolierDelete_Struct
{
/*00*/ uint32 Action;
/*04*/ uint8 Number;
/*05*/ uint8 Unknown05[35];
};
struct BandolierSet_Struct {
/*00*/ uint32 action;
/*04*/ uint8 number;
/*05*/ uint8 unknown05[35];
struct BandolierSet_Struct
{
/*00*/ uint32 Action;
/*04*/ uint8 Number;
/*05*/ uint8 Unknown05[35];
};
struct Arrow_Struct {
@@ -3661,10 +3683,14 @@ struct SendAA_Struct {
/*0069*/ uint32 last_id;
/*0073*/ uint32 next_id;
/*0077*/ uint32 cost2;
/*0081*/ uint8 unknown80[7];
/*0081*/ uint8 unknown81;
/*0082*/ uint8 grant_only; // VetAAs, progression, etc
/*0083*/ uint8 unknown83; // 1 for skill cap increase AAs, Mystical Attuning, and RNG attack inc, doesn't seem to matter though
/*0084*/ uint32 expendable_charges; // max charges of the AA
/*0088*/ uint32 aa_expansion;
/*0092*/ uint32 special_category;
/*0096*/ uint16 unknown0096;
/*0096*/ uint8 shroud;
/*0097*/ uint8 unknown97;
/*0098*/ uint32 total_abilities;
/*0102*/ AA_Ability abilities[0];
};
@@ -3680,12 +3706,6 @@ struct AA_Action {
/*12*/ uint32 exp_value;
};
struct AA_Skills { //this should be removed and changed to AA_Array
/*00*/ uint32 aa_skill; // Total AAs Spent
/*04*/ uint32 aa_value;
/*08*/ uint32 unknown08;
};
struct AAExpUpdate_Struct {
/*00*/ uint32 unknown00; //seems to be a value from AA_Action.ability
/*04*/ uint32 aapoints_unspent;
@@ -3703,12 +3723,12 @@ struct AltAdvStats_Struct {
};
struct PlayerAA_Struct {
AA_Skills aa_list[MAX_PP_AA_ARRAY];
AA_Array aa_list[MAX_PP_AA_ARRAY];
};
struct AATable_Struct {
/*00*/ int32 aa_spent; // Total AAs Spent
/*04*/ AA_Skills aa_list[MAX_PP_AA_ARRAY];
/*04*/ AA_Array aa_list[MAX_PP_AA_ARRAY];
};
struct Weather_Struct {
+7 -2
View File
@@ -41,6 +41,11 @@
memset(__packet->pBuffer, 0, len); \
eq_struct *eq = (eq_struct *) __packet->pBuffer; \
#define ALLOC_LEN_ENCODE(len) \
__packet->pBuffer = new unsigned char[len]; \
__packet->size = len; \
memset(__packet->pBuffer, 0, len); \
//a shorter assignment for direct mode
#undef OUT
#define OUT(x) eq->x = emu->x;
@@ -124,14 +129,14 @@
//check length of packet before decoding. Call before setup.
#define DECODE_LENGTH_EXACT(struct_) \
if(__packet->size != sizeof(struct_)) { \
__packet->SetOpcode(OP_Unknown); /* invalidate the packet */ \
Log.Out(Logs::Detail, Logs::Netcode, "Wrong size on incoming %s (" #struct_ "): Got %d, expected %d", opcodes->EmuToName(__packet->GetOpcode()), __packet->size, sizeof(struct_)); \
__packet->SetOpcode(OP_Unknown); /* invalidate the packet */ \
return; \
}
#define DECODE_LENGTH_ATLEAST(struct_) \
if(__packet->size < sizeof(struct_)) { \
__packet->SetOpcode(OP_Unknown); /* invalidate the packet */ \
Log.Out(Logs::Detail, Logs::Netcode, "Wrong size on incoming %s (" #struct_ "): Got %d, expected at least %d", opcodes->EmuToName(__packet->GetOpcode()), __packet->size, sizeof(struct_)); \
__packet->SetOpcode(OP_Unknown); /* invalidate the packet */ \
return; \
}
+141 -60
View File
@@ -122,7 +122,7 @@ namespace Titanium
EAT_ENCODE(OP_GuildMemberLevelUpdate); // added ;
EAT_ENCODE(OP_ZoneServerReady); // added ;
ENCODE(OP_Action)
{
ENCODE_LENGTH_EXACT(Action_Struct);
@@ -326,7 +326,7 @@ namespace Titanium
{
SETUP_VAR_ENCODE(ExpeditionCompass_Struct);
ALLOC_VAR_ENCODE(structs::ExpeditionCompass_Struct, sizeof(structs::ExpeditionInfo_Struct) + sizeof(structs::ExpeditionCompassEntry_Struct) * emu->count);
OUT(count);
for (uint32 i = 0; i < emu->count; ++i)
@@ -865,7 +865,7 @@ namespace Titanium
// OUT(unknown00178[10]);
for (r = 0; r < 9; r++) {
OUT(item_material[r]);
OUT(item_tint[r].color);
OUT(item_tint[r].Color);
}
// OUT(unknown00224[48]);
for (r = 0; r < structs::MAX_PP_AA_ARRAY; r++) {
@@ -922,24 +922,46 @@ namespace Titanium
OUT(endurance);
OUT(aapoints_spent);
OUT(aapoints);
// OUT(unknown06160[4]);
for (r = 0; r < structs::MAX_PLAYER_BANDOLIER; r++) {
OUT_str(bandoliers[r].name);
uint32 k;
for (k = 0; k < structs::MAX_PLAYER_BANDOLIER_ITEMS; k++) {
OUT(bandoliers[r].items[k].item_id);
OUT(bandoliers[r].items[k].icon);
OUT_str(bandoliers[r].items[k].item_name);
// Copy bandoliers where server and client indexes converge
for (r = 0; r < EmuConstants::BANDOLIERS_SIZE && r < consts::BANDOLIERS_SIZE; ++r) {
OUT_str(bandoliers[r].Name);
for (uint32 k = 0; k < consts::BANDOLIER_ITEM_COUNT; ++k) { // Will need adjusting if 'server != client' is ever true
OUT(bandoliers[r].Items[k].ID);
OUT(bandoliers[r].Items[k].Icon);
OUT_str(bandoliers[r].Items[k].Name);
}
}
// OUT(unknown07444[5120]);
for (r = 0; r < structs::MAX_PLAYER_BANDOLIER_ITEMS; r++) {
OUT(potionbelt.items[r].item_id);
OUT(potionbelt.items[r].icon);
OUT_str(potionbelt.items[r].item_name);
// Nullify bandoliers where server and client indexes diverge, with a client bias
for (r = EmuConstants::BANDOLIERS_SIZE; r < consts::BANDOLIERS_SIZE; ++r) {
eq->bandoliers[r].Name[0] = '\0';
for (uint32 k = 0; k < consts::BANDOLIER_ITEM_COUNT; ++k) { // Will need adjusting if 'server != client' is ever true
eq->bandoliers[r].Items[k].ID = 0;
eq->bandoliers[r].Items[k].Icon = 0;
eq->bandoliers[r].Items[k].Name[0] = '\0';
}
}
// OUT(unknown07444[5120]);
// Copy potion belt where server and client indexes converge
for (r = 0; r < EmuConstants::POTION_BELT_ITEM_COUNT && r < consts::POTION_BELT_ITEM_COUNT; ++r) {
OUT(potionbelt.Items[r].ID);
OUT(potionbelt.Items[r].Icon);
OUT_str(potionbelt.Items[r].Name);
}
// Nullify potion belt where server and client indexes diverge, with a client bias
for (r = EmuConstants::POTION_BELT_ITEM_COUNT; r < consts::POTION_BELT_ITEM_COUNT; ++r) {
eq->potionbelt.Items[r].ID = 0;
eq->potionbelt.Items[r].Icon = 0;
eq->potionbelt.Items[r].Name[0] = '\0';
}
// OUT(unknown12852[8]);
// OUT(unknown12864[76]);
OUT_str(name);
OUT_str(last_name);
OUT(guild_id);
@@ -1048,7 +1070,7 @@ namespace Titanium
ENCODE(OP_ReadBook)
{
// no apparent slot translation needed -U
// no apparent slot translation needed
EQApplicationPacket *in = *p;
*p = nullptr;
@@ -1076,8 +1098,8 @@ namespace Titanium
unsigned int r;
for (r = 0; r < structs::MAX_PP_AA_ARRAY; r++) {
OUT(aa_list[r].aa_skill);
OUT(aa_list[r].aa_value);
OUT(aa_list[r].AA);
OUT(aa_list[r].value);
}
FINISH_ENCODE();
@@ -1133,39 +1155,98 @@ namespace Titanium
ENCODE(OP_SendCharInfo)
{
ENCODE_LENGTH_EXACT(CharacterSelect_Struct);
ENCODE_LENGTH_ATLEAST(CharacterSelect_Struct);
SETUP_DIRECT_ENCODE(CharacterSelect_Struct, structs::CharacterSelect_Struct);
int r;
for (r = 0; r < 10; r++) {
OUT(zone[r]);
OUT(eyecolor1[r]);
OUT(eyecolor2[r]);
OUT(hairstyle[r]);
OUT(primary[r]);
if (emu->race[r] > 473)
eq->race[r] = 1;
else
eq->race[r] = emu->race[r];
OUT(class_[r]);
OUT_str(name[r]);
OUT(gender[r]);
OUT(level[r]);
OUT(secondary[r]);
OUT(face[r]);
OUT(beard[r]);
int k;
for (k = 0; k < 9; k++) {
eq->equip[r][k] = emu->equip[r][k].material;
eq->cs_colors[r][k].color = emu->equip[r][k].color.color;
unsigned char *emu_ptr = __emu_buffer;
emu_ptr += sizeof(CharacterSelect_Struct);
CharacterSelectEntry_Struct *emu_cse = (CharacterSelectEntry_Struct *)nullptr;
for (size_t index = 0; index < 10; ++index) {
memset(eq->Name[index], 0, 64);
}
// Non character-indexed packet fields
eq->Unknown830[0] = 0;
eq->Unknown830[1] = 0;
eq->Unknown0962[0] = 0;
eq->Unknown0962[1] = 0;
size_t char_index = 0;
for (; char_index < emu->CharCount && char_index < 8; ++char_index) {
emu_cse = (CharacterSelectEntry_Struct *)emu_ptr;
eq->Race[char_index] = emu_cse->Race;
if (eq->Race[char_index] > 473)
eq->Race[char_index] = 1;
for (int index = 0; index < _MaterialCount; ++index) {
eq->CS_Colors[char_index][index].Color = emu_cse->Equip[index].Color.Color;
}
OUT(haircolor[r]);
OUT(gohome[r]);
OUT(tutorial[r]);
OUT(deity[r]);
OUT(beardcolor[r]);
eq->unknown820[r] = 0xFF;
eq->unknown902[r] = 0xFF;
eq->BeardColor[char_index] = emu_cse->BeardColor;
eq->HairStyle[char_index] = emu_cse->HairStyle;
for (int index = 0; index < _MaterialCount; ++index) {
eq->Equip[char_index][index] = emu_cse->Equip[index].Material;
}
eq->SecondaryIDFile[char_index] = emu_cse->SecondaryIDFile;
eq->Unknown820[char_index] = (uint8)0xFF;
eq->Deity[char_index] = emu_cse->Deity;
eq->GoHome[char_index] = emu_cse->GoHome;
eq->Tutorial[char_index] = emu_cse->Tutorial;
eq->Beard[char_index] = emu_cse->Beard;
eq->Unknown902[char_index] = (uint8)0xFF;
eq->PrimaryIDFile[char_index] = emu_cse->PrimaryIDFile;
eq->HairColor[char_index] = emu_cse->HairColor;
eq->Zone[char_index] = emu_cse->Zone;
eq->Class[char_index] = emu_cse->Class;
eq->Face[char_index] = emu_cse->Face;
memcpy(eq->Name[char_index], emu_cse->Name, 64);
eq->Gender[char_index] = emu_cse->Gender;
eq->EyeColor1[char_index] = emu_cse->EyeColor1;
eq->EyeColor2[char_index] = emu_cse->EyeColor2;
eq->Level[char_index] = emu_cse->Level;
emu_ptr += sizeof(CharacterSelectEntry_Struct);
}
for (; char_index < 10; ++char_index) {
eq->Race[char_index] = 0;
for (int index = 0; index < _MaterialCount; ++index) {
eq->CS_Colors[char_index][index].Color = 0;
}
eq->BeardColor[char_index] = 0;
eq->HairStyle[char_index] = 0;
for (int index = 0; index < _MaterialCount; ++index) {
eq->Equip[char_index][index] = 0;
}
eq->SecondaryIDFile[char_index] = 0;
eq->Unknown820[char_index] = (uint8)0xFF;
eq->Deity[char_index] = 0;
eq->GoHome[char_index] = 0;
eq->Tutorial[char_index] = 0;
eq->Beard[char_index] = 0;
eq->Unknown902[char_index] = (uint8)0xFF;
eq->PrimaryIDFile[char_index] = 0;
eq->HairColor[char_index] = 0;
eq->Zone[char_index] = 0;
eq->Class[char_index] = 0;
eq->Face[char_index] = 0;
strncpy(eq->Name[char_index], "<none>", 6);
eq->Gender[char_index] = 0;
eq->EyeColor1[char_index] = 0;
eq->EyeColor2[char_index] = 0;
eq->Level[char_index] = 0;
}
FINISH_ENCODE();
@@ -1227,7 +1308,7 @@ namespace Titanium
VARSTRUCT_ENCODE_TYPE(uint8, OutBuffer, emu->unknown12[11]);
VARSTRUCT_ENCODE_STRING(OutBuffer, new_message.c_str());
delete[] __emu_buffer;
dest->FastQueuePacket(&in, ack_req);
}
@@ -1270,7 +1351,7 @@ namespace Titanium
InBuffer += strlen(InBuffer) + 1;
memcpy(OutBuffer, InBuffer, sizeof(TaskDescriptionTrailer_Struct));
delete[] __emu_buffer;
dest->FastQueuePacket(&in, ack_req);
}
@@ -1383,7 +1464,7 @@ namespace Titanium
OUT(spawn_id);
OUT(material);
OUT(color.color);
OUT(color.Color);
OUT(wear_slot_id);
FINISH_ENCODE();
@@ -1468,15 +1549,15 @@ namespace Titanium
eq->beardcolor = emu->beardcolor;
// eq->unknown0147[4] = emu->unknown0147[4];
eq->level = emu->level;
// eq->unknown0259[4] = emu->unknown0259[4];
eq->PlayerState = emu->PlayerState;
eq->beard = emu->beard;
strcpy(eq->suffix, emu->suffix);
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;
eq->equipment[k] = emu->equipment[k].Material;
eq->colors[k].Color = emu->colors[k].Color;
}
for (k = 0; k < 8; k++) {
eq->set_to_0xFF[k] = 0xFF;
@@ -1540,7 +1621,7 @@ namespace Titanium
FINISH_DIRECT_DECODE();
}
DECODE(OP_ApplyPoison)
{
DECODE_LENGTH_EXACT(structs::ApplyPoison_Struct);
@@ -1861,14 +1942,14 @@ namespace Titanium
default:
emu->command = eq->command;
}
OUT(unknown);
IN(target);
FINISH_DIRECT_DECODE();
}
DECODE(OP_ReadBook)
{
// no apparent slot translation needed -U
// no apparent slot translation needed
DECODE_LENGTH_ATLEAST(structs::BookRequest_Struct);
SETUP_DIRECT_DECODE(BookRequest_Struct, structs::BookRequest_Struct);
@@ -1952,7 +2033,7 @@ namespace Titanium
IN(spawn_id);
IN(material);
IN(color.color);
IN(color.Color);
IN(wear_slot_id);
emu->unknown06 = 0;
emu->elite_material = 0;
@@ -2070,7 +2151,7 @@ namespace Titanium
return serverSlot; // deprecated
}
static inline int16 ServerToTitaniumCorpseSlot(uint32 serverCorpseSlot)
{
//int16 TitaniumCorpse;
@@ -2085,7 +2166,7 @@ namespace Titanium
return titaniumSlot; // deprecated
}
static inline uint32 TitaniumToServerCorpseSlot(int16 titaniumCorpseSlot)
{
//uint32 ServerCorpse;
+6 -3
View File
@@ -100,6 +100,8 @@ namespace Titanium {
}
namespace consts {
static const size_t CHARACTER_CREATION_LIMIT = 8; // Hard-coded in client - DO NOT ALTER
static const uint16 MAP_POSSESSIONS_SIZE = slots::_MainCount;
static const uint16 MAP_BANK_SIZE = 16;
static const uint16 MAP_SHARED_BANK_SIZE = 2;
@@ -173,9 +175,10 @@ namespace Titanium {
static const uint16 ITEM_COMMON_SIZE = 5;
static const uint16 ITEM_CONTAINER_SIZE = 10;
static const uint32 BANDOLIERS_COUNT = 4; // count = number of bandolier instances
static const uint32 BANDOLIER_SIZE = 4; // size = number of equipment slots in bandolier instance
static const uint32 POTION_BELT_SIZE = 4;
static const size_t BANDOLIERS_SIZE = 4; // number of bandolier instances
static const size_t BANDOLIER_ITEM_COUNT = 4; // number of equipment slots in bandolier instance
static const size_t POTION_BELT_ITEM_COUNT = 4;
static const size_t TEXT_LINK_BODY_LENGTH = 45;
}
+104 -91
View File
@@ -99,16 +99,14 @@ struct AdventureInfo {
*/
struct Color_Struct
{
union
{
struct
{
uint8 blue;
uint8 green;
uint8 red;
uint8 use_tint; // if there's a tint this is FF
} rgb;
uint32 color;
union {
struct {
uint8 Blue;
uint8 Green;
uint8 Red;
uint8 UseTint; // if there's a tint this is FF
} RGB;
uint32 Color;
};
};
@@ -117,31 +115,32 @@ struct Color_Struct
** Length: 1704 Bytes
**
*/
struct CharacterSelect_Struct {
/*0000*/ uint32 race[10]; // Characters Race
/*0040*/ Color_Struct cs_colors[10][9]; // Characters Equipment Colors
/*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)
/*0780*/ uint32 secondary[10]; // Characters secondary IDFile number
/*0820*/ uint8 unknown820[10]; // 10x ff
/*0830*/ uint8 unknown830[2]; // 2x 00
/*0832*/ uint32 deity[10]; // Characters Deity
/*0872*/ uint8 gohome[10]; // 1=Go Home available, 0=not
/*0882*/ uint8 tutorial[10]; // 1=Tutorial available, 0=not
/*0892*/ uint8 beard[10]; // Characters Beard Type
/*0902*/ uint8 unknown902[10]; // 10x ff
/*0912*/ uint32 primary[10]; // Characters primary IDFile number
/*0952*/ uint8 haircolor[10]; // Characters Hair Color
/*0962*/ uint8 unknown0962[2]; // 2x 00
/*0964*/ uint32 zone[10]; // Characters Current Zone
/*1004*/ uint8 class_[10]; // Characters Classes
/*1014*/ uint8 face[10]; // Characters Face Type
/*1024*/ char name[10][64]; // Characters Names
/*1664*/ uint8 gender[10]; // Characters Gender
/*1674*/ uint8 eyecolor1[10]; // Characters Eye Color
/*1684*/ uint8 eyecolor2[10]; // Characters Eye 2 Color
/*1694*/ uint8 level[10]; // Characters Levels
struct CharacterSelect_Struct
{
/*0000*/ uint32 Race[10]; // Characters Race
/*0040*/ Color_Struct CS_Colors[10][9]; // Characters Equipment Colors
/*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)
/*0780*/ uint32 SecondaryIDFile[10]; // Characters secondary IDFile number
/*0820*/ uint8 Unknown820[10]; // 10x ff
/*0830*/ uint8 Unknown830[2]; // 2x 00
/*0832*/ uint32 Deity[10]; // Characters Deity
/*0872*/ uint8 GoHome[10]; // 1=Go Home available, 0=not
/*0882*/ uint8 Tutorial[10]; // 1=Tutorial available, 0=not
/*0892*/ uint8 Beard[10]; // Characters Beard Type
/*0902*/ uint8 Unknown902[10]; // 10x ff
/*0912*/ uint32 PrimaryIDFile[10]; // Characters primary IDFile number
/*0952*/ uint8 HairColor[10]; // Characters Hair Color
/*0962*/ uint8 Unknown0962[2]; // 2x 00
/*0964*/ uint32 Zone[10]; // Characters Current Zone
/*1004*/ uint8 Class[10]; // Characters Classes
/*1014*/ uint8 Face[10]; // Characters Face Type
/*1024*/ char Name[10][64]; // Characters Names
/*1664*/ uint8 Gender[10]; // Characters Gender
/*1674*/ uint8 EyeColor1[10]; // Characters Eye Color
/*1684*/ uint8 EyeColor2[10]; // Characters Eye 2 Color
/*1694*/ uint8 Level[10]; // Characters Levels
/*1704*/
};
@@ -213,7 +212,7 @@ struct Spawn_Struct {
/*0146*/ uint8 beardcolor; // Beard color
/*0147*/ uint8 unknown0147[4];
/*0151*/ uint8 level; // Spawn Level
/*0152*/ uint8 unknown0259[4]; // ***Placeholder
/*0152*/ uint32 PlayerState; // PlayerState controls some animation stuff
/*0156*/ uint8 beard; // Beard style
/*0157*/ char suffix[32]; // Player's suffix (of Veeshan, etc.)
/*0189*/ uint32 petOwnerId; // If this is a pet, the spawn id of owner
@@ -446,7 +445,7 @@ struct SpellBuff_Struct
/*002*/ uint8 bard_modifier;
/*003*/ uint8 effect; //not real
/*004*/ uint32 spellid;
/*008*/ uint32 duration;
/*008*/ int32 duration;
/*012*/ uint32 counters;
/*016*/ uint32 player_id; //'global' ID of the caster, for wearoff messages
};
@@ -458,7 +457,7 @@ struct SpellBuffFade_Struct {
/*006*/ uint8 effect;
/*007*/ uint8 unknown7;
/*008*/ uint32 spellid;
/*012*/ uint32 duration;
/*012*/ int32 duration;
/*016*/ uint32 unknown016;
/*020*/ uint32 unknown020; //prolly global player ID
/*024*/ uint32 slotid;
@@ -586,34 +585,48 @@ struct Disciplines_Struct {
};
static const uint32 MAX_PLAYER_TRIBUTES = 5;
static const uint32 MAX_PLAYER_BANDOLIER = 4;
static const uint32 MAX_PLAYER_BANDOLIER_ITEMS = 4;
static const uint32 TRIBUTE_NONE = 0xFFFFFFFF;
struct Tribute_Struct {
uint32 tribute;
uint32 tier;
};
//len = 72
struct BandolierItem_Struct {
uint32 item_id;
uint32 icon;
char item_name[64];
};
//len = 320
enum { //bandolier item positions
bandolierMainHand = 0,
bandolierOffHand,
// Bandolier item positions
enum
{
bandolierPrimary = 0,
bandolierSecondary,
bandolierRange,
bandolierAmmo
};
struct Bandolier_Struct {
char name[32];
BandolierItem_Struct items[MAX_PLAYER_BANDOLIER_ITEMS];
//len = 72
struct BandolierItem_Struct
{
uint32 ID;
uint32 Icon;
char Name[64];
};
struct PotionBelt_Struct {
BandolierItem_Struct items[MAX_PLAYER_BANDOLIER_ITEMS];
//len = 320
struct Bandolier_Struct
{
char Name[32];
BandolierItem_Struct Items[consts::BANDOLIER_ITEM_COUNT];
};
//len = 72
struct PotionBeltItem_Struct
{
uint32 ID;
uint32 Icon;
char Name[64];
};
//len = 288
struct PotionBelt_Struct
{
PotionBeltItem_Struct Items[consts::POTION_BELT_ITEM_COUNT];
};
static const uint32 MAX_GROUP_LEADERSHIP_AA_ARRAY = 16;
@@ -817,7 +830,7 @@ struct PlayerProfile_Struct
/*06152*/ uint32 aapoints_spent; // Number of spent AA points
/*06156*/ uint32 aapoints; // Unspent AA points
/*06160*/ uint8 unknown06160[4];
/*06164*/ Bandolier_Struct bandoliers[MAX_PLAYER_BANDOLIER]; // bandolier contents
/*06164*/ Bandolier_Struct bandoliers[consts::BANDOLIERS_SIZE]; // bandolier contents
/*07444*/ uint8 unknown07444[5120];
/*12564*/ PotionBelt_Struct potionbelt; // potion belt
/*12852*/ uint8 unknown12852[8];
@@ -937,7 +950,7 @@ struct TargetReject_Struct {
struct PetCommand_Struct {
/*000*/ uint32 command;
/*004*/ uint32 unknown;
/*004*/ uint32 target;
};
/*
@@ -1049,8 +1062,8 @@ struct RequestClientZoneChange_Struct {
struct Animation_Struct {
/*00*/ uint16 spawnid;
/*02*/ uint8 action;
/*03*/ uint8 value;
/*02*/ uint8 speed;
/*03*/ uint8 action;
/*04*/
};
@@ -1088,9 +1101,9 @@ struct CombatDamage_Struct
/* 04 */ uint8 type; //slashing, etc. 231 (0xE7) for spells
/* 05 */ uint16 spellid;
/* 07 */ uint32 damage;
/* 11 */ uint32 unknown11;
/* 15 */ uint32 sequence; // see above notes in Action_Struct
/* 19 */ uint32 unknown19;
/* 11 */ float force;
/* 15 */ float meleepush_xy; // see above notes in Action_Struct
/* 19 */ float meleepush_z;
/* 23 */
};
@@ -1997,7 +2010,7 @@ struct BookRequest_Struct {
**
*/
struct Object_Struct {
/*00*/ uint32 linked_list_addr[2];// <Zaphod> They are, get this, prev and next, ala linked list
/*00*/ uint32 linked_list_addr[2];// They are, get this, prev and next, ala linked list
/*08*/ uint16 unknown008[2]; //
/*12*/ uint32 drop_id; // Unique object id for zone
/*16*/ uint16 zone_id; // Redudant, but: Zone the object appears in
@@ -2016,8 +2029,8 @@ struct Object_Struct {
/*88*/ uint32 spawn_id; // Spawn Id of client interacting with object
/*92*/
};
//<Zaphod> 01 = generic drop, 02 = armor, 19 = weapon
//[13:40] <Zaphod> and 0xff seems to be indicative of the tradeskill/openable items that end up returning the old style item type in the OP_OpenObject
//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
/*
** Click Object Struct
@@ -3030,30 +3043,35 @@ struct DynamicWall_Struct {
/*80*/
};
enum { //bandolier actions
BandolierCreate = 0,
BandolierRemove = 1,
BandolierSet = 2
// Bandolier actions
enum
{
bandolierCreate = 0,
bandolierRemove,
bandolierSet
};
struct BandolierCreate_Struct {
/*00*/ uint32 action; //0 for create
/*04*/ uint8 number;
/*05*/ char name[32];
/*37*/ uint16 unknown37; //seen 0x93FD
/*39*/ uint8 unknown39; //0
struct BandolierCreate_Struct
{
/*00*/ uint32 Action; //0 for create
/*04*/ uint8 Number;
/*05*/ char Name[32];
/*37*/ uint16 Unknown37; //seen 0x93FD
/*39*/ uint8 Unknown39; //0
};
struct BandolierDelete_Struct {
/*00*/ uint32 action;
/*04*/ uint8 number;
/*05*/ uint8 unknown05[35];
struct BandolierDelete_Struct
{
/*00*/ uint32 Action;
/*04*/ uint8 Number;
/*05*/ uint8 Unknown05[35];
};
struct BandolierSet_Struct {
/*00*/ uint32 action;
/*04*/ uint8 number;
/*05*/ uint8 unknown05[35];
struct BandolierSet_Struct
{
/*00*/ uint32 Action;
/*04*/ uint8 Number;
/*05*/ uint8 Unknown05[35];
};
struct Arrow_Struct {
@@ -3161,11 +3179,6 @@ struct AA_Action {
/*12*/ uint32 exp_value;
};
struct AA_Skills { //this should be removed and changed to AA_Array
/*00*/ uint32 aa_skill;
/*04*/ uint32 aa_value;
};
struct AAExpUpdate_Struct {
/*00*/ uint32 unknown00; //seems to be a value from AA_Action.ability
/*04*/ uint32 aapoints_unspent;
@@ -3183,11 +3196,11 @@ struct AltAdvStats_Struct {
};
struct PlayerAA_Struct {
AA_Skills aa_list[MAX_PP_AA_ARRAY];
AA_Array aa_list[MAX_PP_AA_ARRAY];
};
struct AATable_Struct {
AA_Skills aa_list[MAX_PP_AA_ARRAY];
AA_Array aa_list[MAX_PP_AA_ARRAY];
};
struct Weather_Struct {
+162 -130
View File
@@ -387,7 +387,7 @@ namespace UF
__packet->WriteUInt32(emu->entries[i].num_hits);
__packet->WriteString("");
}
__packet->WriteUInt8(!emu->all_buffs);
__packet->WriteUInt8(emu->type);
FINISH_ENCODE();
/*
@@ -581,7 +581,9 @@ namespace UF
OUT(type);
OUT(spellid);
OUT(damage);
eq->sequence = emu->sequence;
OUT(force)
OUT(meleepush_xy);
OUT(meleepush_z)
FINISH_ENCODE();
}
@@ -855,8 +857,8 @@ namespace UF
// 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(uint32, OutBuffer, 0);
VARSTRUCT_ENCODE_TYPE(uint32, OutBuffer, 0); // Unknown, observed 0
VARSTRUCT_ENCODE_TYPE(uint32, OutBuffer, 0); // This appears to be the size field.
VARSTRUCT_ENCODE_TYPE(uint32, OutBuffer, emu->solidtype); // Unknown, observed 0
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);
VARSTRUCT_ENCODE_TYPE(float, OutBuffer, emu->z);
@@ -1791,13 +1793,13 @@ namespace UF
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;
eq->equipment[r].Material = emu->item_material[r];
eq->equipment[r].Unknown1 = 0;
eq->equipment[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[r].Color);
}
// OUT(unknown00224[48]);
//NOTE: new client supports 300 AAs, our internal rep/PP
@@ -1805,6 +1807,7 @@ namespace UF
for (r = 0; r < MAX_PP_AA_ARRAY; r++) {
OUT(aa_array[r].AA);
OUT(aa_array[r].value);
OUT(aa_array[r].charges);
}
// OUT(unknown02220[4]);
OUT(mana);
@@ -1868,26 +1871,46 @@ namespace UF
OUT(endurance);
OUT(aapoints_spent);
OUT(aapoints);
// OUT(unknown06160[4]);
//NOTE: new client supports 20 bandoliers, our internal rep
//only supports 4..
for (r = 0; r < 4; r++) {
OUT_str(bandoliers[r].name);
uint32 k;
for (k = 0; k < structs::MAX_PLAYER_BANDOLIER_ITEMS; k++) {
OUT(bandoliers[r].items[k].item_id);
OUT(bandoliers[r].items[k].icon);
OUT_str(bandoliers[r].items[k].item_name);
// Copy bandoliers where server and client indexes converge
for (r = 0; r < EmuConstants::BANDOLIERS_SIZE && r < consts::BANDOLIERS_SIZE; ++r) {
OUT_str(bandoliers[r].Name);
for (uint32 k = 0; k < consts::BANDOLIER_ITEM_COUNT; ++k) { // Will need adjusting if 'server != client' is ever true
OUT(bandoliers[r].Items[k].ID);
OUT(bandoliers[r].Items[k].Icon);
OUT_str(bandoliers[r].Items[k].Name);
}
}
// OUT(unknown07444[5120]);
for (r = 0; r < structs::MAX_POTIONS_IN_BELT; r++) {
OUT(potionbelt.items[r].item_id);
OUT(potionbelt.items[r].icon);
OUT_str(potionbelt.items[r].item_name);
// Nullify bandoliers where server and client indexes diverge, with a client bias
for (r = EmuConstants::BANDOLIERS_SIZE; r < consts::BANDOLIERS_SIZE; ++r) {
eq->bandoliers[r].Name[0] = '\0';
for (uint32 k = 0; k < consts::BANDOLIER_ITEM_COUNT; ++k) { // Will need adjusting if 'server != client' is ever true
eq->bandoliers[r].Items[k].ID = 0;
eq->bandoliers[r].Items[k].Icon = 0;
eq->bandoliers[r].Items[k].Name[0] = '\0';
}
}
// OUT(unknown07444[5120]);
// Copy potion belt where server and client indexes converge
for (r = 0; r < EmuConstants::POTION_BELT_ITEM_COUNT && r < consts::POTION_BELT_ITEM_COUNT; ++r) {
OUT(potionbelt.Items[r].ID);
OUT(potionbelt.Items[r].Icon);
OUT_str(potionbelt.Items[r].Name);
}
// Nullify potion belt where server and client indexes diverge, with a client bias
for (r = EmuConstants::POTION_BELT_ITEM_COUNT; r < consts::POTION_BELT_ITEM_COUNT; ++r) {
eq->potionbelt.Items[r].ID = 0;
eq->potionbelt.Items[r].Icon = 0;
eq->potionbelt.Items[r].Name[0] = '\0';
}
// OUT(unknown12852[8]);
// OUT(unknown12864[76]);
OUT_str(name);
OUT_str(last_name);
OUT(guild_id);
@@ -2112,9 +2135,9 @@ namespace UF
for (uint32 i = 0; i < MAX_PP_AA_ARRAY; ++i)
{
eq->aa_list[i].aa_skill = emu->aa_list[i].aa_skill;
eq->aa_list[i].aa_value = emu->aa_list[i].aa_value;
eq->aa_list[i].unknown08 = emu->aa_list[i].unknown08;
eq->aa_list[i].AA = emu->aa_list[i].AA;
eq->aa_list[i].value = emu->aa_list[i].value;
eq->aa_list[i].charges = emu->aa_list[i].charges;
}
FINISH_ENCODE();
@@ -2159,6 +2182,7 @@ namespace UF
OUT(cost2);
eq->aa_expansion = emu->aa_expansion;
eq->special_category = emu->special_category;
eq->expendable_charges = emu->special_category == 7 ? 1 : 0; // temp hack, this can actually be any number
OUT(total_abilities);
unsigned int r;
for (r = 0; r < emu->total_abilities; r++) {
@@ -2174,77 +2198,104 @@ namespace UF
ENCODE(OP_SendCharInfo)
{
ENCODE_LENGTH_EXACT(CharacterSelect_Struct);
ENCODE_LENGTH_ATLEAST(CharacterSelect_Struct);
SETUP_VAR_ENCODE(CharacterSelect_Struct);
//EQApplicationPacket *packet = *p;
//const CharacterSelect_Struct *emu = (CharacterSelect_Struct *) packet->pBuffer;
// Zero-character count shunt
if (emu->CharCount == 0) {
ALLOC_VAR_ENCODE(structs::CharacterSelect_Struct, sizeof(structs::CharacterSelect_Struct));
eq->CharCount = emu->CharCount;
eq->TotalChars = emu->TotalChars;
int char_count;
int namelen = 0;
for (char_count = 0; char_count < 10; char_count++) {
if (emu->name[char_count][0] == '\0')
break;
if (strcmp(emu->name[char_count], "<none>") == 0)
break;
namelen += strlen(emu->name[char_count]);
if (eq->TotalChars > consts::CHARACTER_CREATION_LIMIT)
eq->TotalChars = consts::CHARACTER_CREATION_LIMIT;
// Special Underfoot adjustment - field should really be 'AdditionalChars' or 'BonusChars'
uint32 adjusted_total = eq->TotalChars - 8; // Yes, it rolls under for '< 8' - probably an int32 field
eq->TotalChars = adjusted_total;
FINISH_ENCODE();
return;
}
int total_length = sizeof(structs::CharacterSelect_Struct)
+ char_count * sizeof(structs::CharacterSelectEntry_Struct)
+ namelen;
unsigned char *emu_ptr = __emu_buffer;
emu_ptr += sizeof(CharacterSelect_Struct);
CharacterSelectEntry_Struct *emu_cse = (CharacterSelectEntry_Struct *)nullptr;
size_t names_length = 0;
size_t character_count = 0;
for (; character_count < emu->CharCount && character_count < consts::CHARACTER_CREATION_LIMIT; ++character_count) {
emu_cse = (CharacterSelectEntry_Struct *)emu_ptr;
names_length += strlen(emu_cse->Name);
emu_ptr += sizeof(CharacterSelectEntry_Struct);
}
size_t total_length = sizeof(structs::CharacterSelect_Struct)
+ character_count * sizeof(structs::CharacterSelectEntry_Struct)
+ names_length;
ALLOC_VAR_ENCODE(structs::CharacterSelect_Struct, total_length);
structs::CharacterSelectEntry_Struct *eq_cse = (structs::CharacterSelectEntry_Struct *)nullptr;
//unsigned char *eq_buffer = new unsigned char[total_length];
//structs::CharacterSelect_Struct *eq_head = (structs::CharacterSelect_Struct *) eq_buffer;
eq->CharCount = character_count;
eq->TotalChars = emu->TotalChars;
eq->char_count = char_count;
eq->total_chars = 10;
if (eq->TotalChars > consts::CHARACTER_CREATION_LIMIT)
eq->TotalChars = consts::CHARACTER_CREATION_LIMIT;
unsigned char *bufptr = (unsigned char *)eq->entries;
int r;
for (r = 0; r < char_count; r++) {
{ //pre-name section...
structs::CharacterSelectEntry_Struct *eq2 = (structs::CharacterSelectEntry_Struct *) bufptr;
eq2->level = emu->level[r];
eq2->hairstyle = emu->hairstyle[r];
eq2->gender = emu->gender[r];
memcpy(eq2->name, emu->name[r], strlen(emu->name[r]) + 1);
}
//adjust for name.
bufptr += strlen(emu->name[r]);
{ //post-name section...
structs::CharacterSelectEntry_Struct *eq2 = (structs::CharacterSelectEntry_Struct *) bufptr;
eq2->beard = emu->beard[r];
eq2->haircolor = emu->haircolor[r];
eq2->face = emu->face[r];
int k;
for (k = 0; k < _MaterialCount; k++) {
eq2->equip[k].material = emu->equip[r][k].material;
eq2->equip[k].unknown1 = emu->equip[r][k].unknown1;
eq2->equip[k].elitematerial = emu->equip[r][k].elitematerial;
eq2->equip[k].color.color = emu->equip[r][k].color.color;
}
eq2->primary = emu->primary[r];
eq2->secondary = emu->secondary[r];
eq2->tutorial = emu->tutorial[r]; // was u15
eq2->u15 = 0xff;
eq2->deity = emu->deity[r];
eq2->zone = emu->zone[r];
eq2->u19 = 0xFF;
eq2->race = emu->race[r];
eq2->gohome = emu->gohome[r];
eq2->class_ = emu->class_[r];
eq2->eyecolor1 = emu->eyecolor1[r];
eq2->beardcolor = emu->beardcolor[r];
eq2->eyecolor2 = emu->eyecolor2[r];
eq2->drakkin_heritage = emu->drakkin_heritage[r];
eq2->drakkin_tattoo = emu->drakkin_tattoo[r];
eq2->drakkin_details = emu->drakkin_details[r];
// Special Underfoot adjustment - field should really be 'AdditionalChars' or 'BonusChars' in this client
uint32 adjusted_total = eq->TotalChars - 8; // Yes, it rolls under for '< 8' - probably an int32 field
eq->TotalChars = adjusted_total;
emu_ptr = __emu_buffer;
emu_ptr += sizeof(CharacterSelect_Struct);
unsigned char *eq_ptr = __packet->pBuffer;
eq_ptr += sizeof(structs::CharacterSelect_Struct);
for (int counter = 0; counter < character_count; ++counter) {
emu_cse = (CharacterSelectEntry_Struct *)emu_ptr;
eq_cse = (structs::CharacterSelectEntry_Struct *)eq_ptr; // base address
eq_cse->Level = emu_cse->Level;
eq_cse->HairStyle = emu_cse->HairStyle;
eq_cse->Gender = emu_cse->Gender;
strcpy(eq_cse->Name, emu_cse->Name);
eq_ptr += strlen(emu_cse->Name);
eq_cse = (structs::CharacterSelectEntry_Struct *)eq_ptr; // offset address (base + name length offset)
eq_cse->Name[0] = '\0'; // (offset)eq_cse->Name[0] = (base)eq_cse->Name[strlen(emu_cse->Name)]
eq_cse->Beard = emu_cse->Beard;
eq_cse->HairColor = emu_cse->HairColor;
eq_cse->Face = emu_cse->Face;
for (int equip_index = 0; equip_index < _MaterialCount; 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;
}
bufptr += sizeof(structs::CharacterSelectEntry_Struct);
eq_cse->PrimaryIDFile = emu_cse->PrimaryIDFile;
eq_cse->SecondaryIDFile = emu_cse->SecondaryIDFile;
eq_cse->Tutorial = emu_cse->Tutorial;
eq_cse->Unknown15 = emu_cse->Unknown15;
eq_cse->Deity = emu_cse->Deity;
eq_cse->Zone = emu_cse->Zone;
eq_cse->Unknown19 = emu_cse->Unknown19;
eq_cse->Race = emu_cse->Race;
eq_cse->GoHome = emu_cse->GoHome;
eq_cse->Class = emu_cse->Class;
eq_cse->EyeColor1 = emu_cse->EyeColor1;
eq_cse->BeardColor = emu_cse->BeardColor;
eq_cse->EyeColor2 = emu_cse->EyeColor2;
eq_cse->DrakkinHeritage = emu_cse->DrakkinHeritage;
eq_cse->DrakkinTattoo = emu_cse->DrakkinTattoo;
eq_cse->DrakkinDetails = emu_cse->DrakkinDetails;
emu_ptr += sizeof(CharacterSelectEntry_Struct);
eq_ptr += sizeof(structs::CharacterSelectEntry_Struct);
}
FINISH_ENCODE();
@@ -2621,7 +2672,7 @@ namespace UF
OUT(material);
OUT(unknown06);
OUT(elite_material);
OUT(color.color);
OUT(color.Color);
OUT(wear_slot_id);
FINISH_ENCODE();
@@ -2693,42 +2744,23 @@ namespace UF
ENCODE(OP_ZonePlayerToBind)
{
ENCODE_LENGTH_ATLEAST(ZonePlayerToBind_Struct);
SETUP_VAR_ENCODE(ZonePlayerToBind_Struct);
ALLOC_LEN_ENCODE(sizeof(structs::ZonePlayerToBind_Struct) + strlen(emu->zone_name));
ZonePlayerToBind_Struct *zps = (ZonePlayerToBind_Struct*)(*p)->pBuffer;
__packet->SetWritePosition(0);
__packet->WriteUInt16(emu->bind_zone_id);
__packet->WriteUInt16(emu->bind_instance_id);
__packet->WriteFloat(emu->x);
__packet->WriteFloat(emu->y);
__packet->WriteFloat(emu->z);
__packet->WriteFloat(emu->heading);
__packet->WriteString(emu->zone_name);
__packet->WriteUInt8(1); // save items
__packet->WriteUInt32(0); // hp
__packet->WriteUInt32(0); // mana
__packet->WriteUInt32(0); // endurance
std::stringstream ss(std::stringstream::in | std::stringstream::out | std::stringstream::binary);
unsigned char *buffer1 = new unsigned char[sizeof(structs::ZonePlayerToBindHeader_Struct) + strlen(zps->zone_name)];
structs::ZonePlayerToBindHeader_Struct *zph = (structs::ZonePlayerToBindHeader_Struct*)buffer1;
unsigned char *buffer2 = new unsigned char[sizeof(structs::ZonePlayerToBindFooter_Struct)];
structs::ZonePlayerToBindFooter_Struct *zpf = (structs::ZonePlayerToBindFooter_Struct*)buffer2;
zph->x = zps->x;
zph->y = zps->y;
zph->z = zps->z;
zph->heading = zps->heading;
zph->bind_zone_id = zps->bind_zone_id;
zph->bind_instance_id = zps->bind_instance_id;
strcpy(zph->zone_name, zps->zone_name);
zpf->unknown021 = 1;
zpf->unknown022 = 0;
zpf->unknown023 = 0;
zpf->unknown024 = 0;
ss.write((const char*)buffer1, (sizeof(structs::ZonePlayerToBindHeader_Struct) + strlen(zps->zone_name)));
ss.write((const char*)buffer2, sizeof(structs::ZonePlayerToBindFooter_Struct));
delete[] buffer1;
delete[] buffer2;
delete[](*p)->pBuffer;
(*p)->pBuffer = new unsigned char[ss.str().size()];
(*p)->size = ss.str().size();
memcpy((*p)->pBuffer, ss.str().c_str(), ss.str().size());
dest->FastQueuePacket(&(*p));
FINISH_ENCODE();
}
ENCODE(OP_ZoneServerInfo)
@@ -2976,7 +3008,7 @@ namespace UF
VARSTRUCT_ENCODE_TYPE(uint8, Buffer, 0); // unknown12
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, emu->petOwnerId);
VARSTRUCT_ENCODE_TYPE(uint8, Buffer, 0); // unknown13
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0); // unknown14 - Stance 64 = normal 4 = aggressive 40 = stun/mezzed
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, emu->PlayerState);
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0); // unknown15
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0); // unknown16
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0); // unknown17
@@ -3002,7 +3034,7 @@ namespace UF
for (k = 0; k < 9; ++k)
{
{
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, emu->colors[k].color);
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, emu->colors[k].Color);
}
}
}
@@ -3012,11 +3044,11 @@ namespace UF
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0);
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0);
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, emu->equipment[MaterialPrimary].material);
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, emu->equipment[MaterialPrimary].Material);
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0);
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0);
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, emu->equipment[MaterialSecondary].material);
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, emu->equipment[MaterialSecondary].Material);
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0);
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0);
}
@@ -3026,9 +3058,9 @@ namespace UF
structs::EquipStruct *Equipment = (structs::EquipStruct *)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].Material = emu->equipment[k].Material;
Equipment[k].Unknown1 = emu->equipment[k].Unknown1;
Equipment[k].EliteMaterial = emu->equipment[k].EliteMaterial;
}
Buffer += (sizeof(structs::EquipStruct) * 9);
@@ -3329,7 +3361,7 @@ namespace UF
IN(type);
IN(spellid);
IN(damage);
emu->sequence = eq->sequence;
IN(meleepush_xy);
FINISH_DIRECT_DECODE();
}
@@ -3572,7 +3604,7 @@ namespace UF
SETUP_DIRECT_DECODE(PetCommand_Struct, structs::PetCommand_Struct);
IN(command);
IN(unknown);
IN(target);
FINISH_DIRECT_DECODE();
}
@@ -3728,7 +3760,7 @@ namespace UF
IN(material);
IN(unknown06);
IN(elite_material);
IN(color.color);
IN(color.Color);
IN(wear_slot_id);
emu->hero_forge_model = 0;
emu->unknown18 = 0;
@@ -3834,7 +3866,7 @@ namespace UF
UF::structs::ItemSerializationHeaderFinish hdrf;
hdrf.ornamentIcon = ornaIcon;
hdrf.unknown060 = 0; //This is Always 0.. or it breaks shit..
hdrf.unknown060 = 0; //This is Always 0.. or it breaks shit..
hdrf.unknown061 = 0; //possibly ornament / special ornament
hdrf.isCopied = 0; //Flag for item to be 'Copied'
hdrf.ItemClass = item->ItemClass;
+6 -3
View File
@@ -101,6 +101,8 @@ namespace UF {
}
namespace consts {
static const size_t CHARACTER_CREATION_LIMIT = 12;
static const uint16 MAP_POSSESSIONS_SIZE = slots::_MainCount;
static const uint16 MAP_BANK_SIZE = 24;
static const uint16 MAP_SHARED_BANK_SIZE = 2;
@@ -174,9 +176,10 @@ namespace UF {
static const uint16 ITEM_COMMON_SIZE = 5;
static const uint16 ITEM_CONTAINER_SIZE = 10;
static const uint32 BANDOLIERS_COUNT = 20; // count = number of bandolier instances
static const uint32 BANDOLIER_SIZE = 4; // size = number of equipment slots in bandolier instance
static const uint32 POTION_BELT_SIZE = 5;
static const size_t BANDOLIERS_SIZE = 20; // number of bandolier instances
static const size_t BANDOLIER_ITEM_COUNT = 4; // number of equipment slots in bandolier instance
static const size_t POTION_BELT_ITEM_COUNT = 5;
static const size_t TEXT_LINK_BODY_LENGTH = 50;
}
+134 -112
View File
@@ -103,53 +103,53 @@ struct AdventureInfo {
*/
struct Color_Struct
{
union
{
struct
{
uint8 blue;
uint8 green;
uint8 red;
uint8 use_tint; // if there's a tint this is FF
} rgb;
uint32 color;
union {
struct {
uint8 blue;
uint8 Green;
uint8 Red;
uint8 UseTint; // if there's a tint this is FF
} RGB;
uint32 Color;
};
};
struct CharSelectEquip {
uint32 material;
uint32 unknown1;
uint32 elitematerial;
Color_Struct color;
struct CharSelectEquip
{
uint32 Material;
uint32 Unknown1;
uint32 EliteMaterial;
Color_Struct Color;
};
struct CharacterSelectEntry_Struct {
/*0000*/ uint8 level; //
/*0000*/ uint8 hairstyle; //
/*0002*/ uint8 gender; //
/*0003*/ char name[1]; //variable length, edi+0
/*0000*/ uint8 beard; //
/*0001*/ uint8 haircolor; //
/*0000*/ uint8 face; //
/*0000*/ CharSelectEquip equip[9];
/*0000*/ uint32 primary; //
/*0000*/ uint32 secondary; //
/*0000*/ uint8 u15; // 0xff
/*0000*/ uint32 deity; //
/*0000*/ uint16 zone; //
/*0000*/ uint16 instance;
/*0000*/ uint8 gohome; //
/*0000*/ uint8 u19; // 0xff
/*0000*/ uint32 race; //
/*0000*/ uint8 tutorial; //
/*0000*/ uint8 class_; //
/*0000*/ uint8 eyecolor1; //
/*0000*/ uint8 beardcolor; //
/*0000*/ uint8 eyecolor2; //
/*0000*/ uint32 drakkin_heritage; // Drakkin Heritage
/*0000*/ uint32 drakkin_tattoo; // Drakkin Tattoo
/*0000*/ uint32 drakkin_details; // Drakkin Details (Facial Spikes)
/*0000*/ uint8 unknown; // New field to Underfoot
struct CharacterSelectEntry_Struct
{
/*0000*/ uint8 Level; //
/*0000*/ uint8 HairStyle; //
/*0002*/ uint8 Gender; //
/*0003*/ char Name[1]; // variable length, edi+0
/*0000*/ uint8 Beard; //
/*0001*/ uint8 HairColor; //
/*0000*/ uint8 Face; //
/*0000*/ CharSelectEquip Equip[9];
/*0000*/ uint32 PrimaryIDFile; //
/*0000*/ uint32 SecondaryIDFile; //
/*0000*/ uint8 Unknown15; // 0xff
/*0000*/ uint32 Deity; //
/*0000*/ uint16 Zone; //
/*0000*/ uint16 Instance;
/*0000*/ uint8 GoHome; //
/*0000*/ uint8 Unknown19; // 0xff
/*0000*/ uint32 Race; //
/*0000*/ uint8 Tutorial; //
/*0000*/ uint8 Class; //
/*0000*/ uint8 EyeColor1; //
/*0000*/ uint8 BeardColor; //
/*0000*/ uint8 EyeColor2; //
/*0000*/ uint32 DrakkinHeritage; // Drakkin Heritage
/*0000*/ uint32 DrakkinTattoo; // Drakkin Tattoo
/*0000*/ uint32 DrakkinDetails; // Drakkin Details (Facial Spikes)
/*0000*/ uint8 Unknown; // New field to Underfoot
};
@@ -157,20 +157,22 @@ struct CharacterSelectEntry_Struct {
** Character Selection Struct
**
*/
struct CharacterSelect_Struct {
/*0000*/ uint32 char_count; //number of chars in this packet
/*0004*/ uint32 total_chars; //total number of chars allowed?
/*0008*/ CharacterSelectEntry_Struct entries[0];
struct CharacterSelect_Struct
{
/*0000*/ uint32 CharCount; //number of chars in this packet
/*0004*/ uint32 TotalChars; //total number of chars allowed?
/*0008*/ CharacterSelectEntry_Struct Entries[0];
};
/*
* Visible equiptment.
* Size: 12 Octets
*/
struct EquipStruct {
/*00*/ uint32 material;
/*04*/ uint32 unknown1;
/*08*/ uint32 elitematerial;
struct EquipStruct
{
/*00*/ uint32 Material;
/*04*/ uint32 Unknown1;
/*08*/ uint32 EliteMaterial;
/*12*/
};
@@ -284,7 +286,7 @@ struct Spawn_Struct
/*0000*/ uint8 unknown12;
/*0000*/ uint32 petOwnerId;
/*0000*/ uint8 unknown13;
/*0000*/ uint32 unknown14; // Stance 64 = normal 4 = aggressive 40 = stun/mezzed
/*0000*/ uint32 PlayerState; // Stance 64 = normal 4 = aggressive 40 = stun/mezzed
/*0000*/ uint32 unknown15;
/*0000*/ uint32 unknown16;
/*0000*/ uint32 unknown17;
@@ -549,7 +551,7 @@ struct SpellBuff_Struct
/*003*/ uint8 effect; // not real
/*004*/ uint32 unknown004; // Seen 1 for no buff
/*008*/ uint32 spellid;
/*012*/ uint32 duration;
/*012*/ int32 duration;
/*016*/ uint32 unknown016;
/*020*/ uint32 player_id; // 'global' ID of the caster, for wearoff messages
/*024*/ uint32 counters;
@@ -566,7 +568,7 @@ struct SpellBuffFade_Struct_Underfoot {
/*007*/ uint8 unknown7;
/*008*/ float unknown008;
/*012*/ uint32 spellid;
/*016*/ uint32 duration;
/*016*/ int32 duration;
/*020*/ uint32 num_hits;
/*024*/ uint32 playerId; // Global player ID?
/*028*/ uint32 unknown020;
@@ -583,7 +585,7 @@ struct SpellBuffFade_Struct {
/*006*/ uint8 effect;
/*007*/ uint8 unknown7;
/*008*/ uint32 spellid;
/*012*/ uint32 duration;
/*012*/ int32 duration;
/*016*/ uint32 unknown016;
/*020*/ uint32 unknown020; // Global player ID?
/*024*/ uint32 playerId; // Player id who cast the buff
@@ -711,7 +713,7 @@ struct AA_Array
{
uint32 AA;
uint32 value;
uint32 unknown08; // Looks like AA_Array is now 12 bytes in Underfoot
uint32 charges; // expendable
};
@@ -722,9 +724,6 @@ struct Disciplines_Struct {
};
static const uint32 MAX_PLAYER_TRIBUTES = 5;
static const uint32 MAX_PLAYER_BANDOLIER = 20;
static const uint32 MAX_PLAYER_BANDOLIER_ITEMS = 4;
static const uint32 MAX_POTIONS_IN_BELT = 5;
static const uint32 TRIBUTE_NONE = 0xFFFFFFFF;
struct Tribute_Struct {
@@ -732,26 +731,42 @@ struct Tribute_Struct {
uint32 tier;
};
//len = 72
struct BandolierItem_Struct {
uint32 item_id;
uint32 icon;
char item_name[64];
};
//len = 320
enum { //bandolier item positions
bandolierMainHand = 0,
bandolierOffHand,
// Bandolier item positions
enum
{
bandolierPrimary = 0,
bandolierSecondary,
bandolierRange,
bandolierAmmo
};
struct Bandolier_Struct {
char name[32];
BandolierItem_Struct items[MAX_PLAYER_BANDOLIER_ITEMS];
//len = 72
struct BandolierItem_Struct
{
uint32 ID;
uint32 Icon;
char Name[64];
};
struct PotionBelt_Struct {
BandolierItem_Struct items[MAX_POTIONS_IN_BELT];
//len = 320
struct Bandolier_Struct
{
char Name[32];
BandolierItem_Struct Items[consts::BANDOLIER_ITEM_COUNT];
};
//len = 72
struct PotionBeltItem_Struct
{
uint32 ID;
uint32 Icon;
char Name[64];
};
//len = 288
struct PotionBelt_Struct
{
PotionBeltItem_Struct Items[consts::POTION_BELT_ITEM_COUNT];
};
static const uint32 MAX_GROUP_LEADERSHIP_AA_ARRAY = 16;
@@ -974,7 +989,7 @@ struct PlayerProfile_Struct
/*11236*/ uint32 aapoints_spent; // Number of spent AA points
/*11240*/ uint32 aapoints; // Unspent AA points
/*11244*/ uint8 unknown11244[4];
/*11248*/ Bandolier_Struct bandoliers[MAX_PLAYER_BANDOLIER]; // [6400] bandolier contents
/*11248*/ Bandolier_Struct bandoliers[consts::BANDOLIERS_SIZE]; // [6400] bandolier contents
/*17648*/ PotionBelt_Struct potionbelt; // [360] potion belt 72 extra octets by adding 1 more belt slot
/*18008*/ uint8 unknown18008[8];
/*18016*/ uint32 available_slots;
@@ -1131,7 +1146,7 @@ struct TargetReject_Struct {
struct PetCommand_Struct {
/*000*/ uint32 command;
/*004*/ uint32 unknown;
/*004*/ uint32 target;
};
/*
@@ -1245,8 +1260,8 @@ struct RequestClientZoneChange_Struct {
struct Animation_Struct {
/*00*/ uint16 spawnid;
/*02*/ uint8 action;
/*03*/ uint8 value;
/*02*/ uint8 speed;
/*03*/ uint8 action;
/*04*/
};
@@ -1315,9 +1330,10 @@ struct CombatDamage_Struct
/* 04 */ uint8 type; //slashing, etc. 231 (0xE7) for spells
/* 05 */ uint16 spellid;
/* 07 */ int32 damage;
/* 11 */ float unknown11; // cd cc cc 3d
/* 15 */ float sequence; // see above notes in Action_Struct
/* 19 */ uint8 unknown19[9]; // was [9]
/* 11 */ float force; // cd cc cc 3d
/* 15 */ float meleepush_xy; // see above notes in Action_Struct
/* 19 */ float meleepush_z;
/* 23 */ uint8 unknown23[5]; // was [9]
/* 28 */
};
@@ -2172,7 +2188,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*/ uint32 tics_remaining[BUFF_COUNT];
/*120*/ int32 tics_remaining[BUFF_COUNT];
/*220*/ uint32 filler220[5]; // BUFF_COUNT is really 30...
};
@@ -2425,7 +2441,7 @@ struct BookRequest_Struct {
**
*/
struct Object_Struct {
/*00*/ uint32 linked_list_addr[2];// <Zaphod> They are, get this, prev and next, ala linked list
/*00*/ uint32 linked_list_addr[2];// They are, get this, prev and next, ala linked list
/*08*/ uint32 unknown008; // Something related to the linked list?
/*12*/ uint32 drop_id; // Unique object id for zone
/*16*/ uint16 zone_id; // Redudant, but: Zone the object appears in
@@ -2445,8 +2461,8 @@ struct Object_Struct {
/*100*/ uint32 spawn_id; // Spawn Id of client interacting with object
/*104*/
};
//<Zaphod> 01 = generic drop, 02 = armor, 19 = weapon
//[13:40] <Zaphod> and 0xff seems to be indicative of the tradeskill/openable items that end up returning the old style item type in the OP_OpenObject
//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
/*
** Click Object Struct
@@ -3758,30 +3774,35 @@ struct DynamicWall_Struct {
/*80*/
};
enum { //bandolier actions
BandolierCreate = 0,
BandolierRemove = 1,
BandolierSet = 2
// Bandolier actions
enum
{
bandolierCreate = 0,
bandolierRemove,
bandolierSet
};
struct BandolierCreate_Struct {
/*00*/ uint32 action; //0 for create
/*04*/ uint8 number;
/*05*/ char name[32];
/*37*/ uint16 unknown37; //seen 0x93FD
/*39*/ uint8 unknown39; //0
struct BandolierCreate_Struct
{
/*00*/ uint32 Action; //0 for create
/*04*/ uint8 Number;
/*05*/ char Name[32];
/*37*/ uint16 Unknown37; //seen 0x93FD
/*39*/ uint8 Unknown39; //0
};
struct BandolierDelete_Struct {
/*00*/ uint32 action;
/*04*/ uint8 number;
/*05*/ uint8 unknown05[35];
struct BandolierDelete_Struct
{
/*00*/ uint32 Action;
/*04*/ uint8 Number;
/*05*/ uint8 Unknown05[35];
};
struct BandolierSet_Struct {
/*00*/ uint32 action;
/*04*/ uint8 number;
/*05*/ uint8 unknown05[35];
struct BandolierSet_Struct
{
/*00*/ uint32 Action;
/*04*/ uint8 Number;
/*05*/ uint8 Unknown05[35];
};
// Not 100% sure on this struct. Live as of 1/1/11 is different than UF. Seems to work 'OK'
@@ -3871,10 +3892,16 @@ struct SendAA_Struct {
/*0069*/ uint32 last_id;
/*0073*/ uint32 next_id;
/*0077*/ uint32 cost2;
/*0081*/ uint8 unknown80[7];
/*0081*/ uint8 unknown81;
/*0082*/ uint8 grant_only; // VetAAs, progression, etc
/*0083*/ uint8 unknown83; // 1 for skill cap increase AAs, Mystical Attuning, and RNG attack inc, doesn't seem to matter though
/*0084*/ uint32 expendable_charges; // max charges of the AA
/*0088*/ uint32 aa_expansion;
/*0092*/ uint32 special_category;
/*0096*/ uint32 unknown0096;
/*0096*/ uint8 shroud;
/*0097*/ uint8 unknown97;
/*0098*/ uint8 layonhands; // 1 for lay on hands -- doesn't seem to matter?
/*0099*/ uint8 unknown99;
/*0100*/ uint32 total_abilities;
/*0104*/ AA_Ability abilities[0];
};
@@ -3890,11 +3917,6 @@ struct AA_Action {
/*12*/ uint32 exp_value;
};
struct AA_Skills { //this should be removed and changed to AA_Array
/*00*/ uint32 aa_skill; // Total AAs Spent
/*04*/ uint32 aa_value;
/*08*/ uint32 unknown08;
};
struct AAExpUpdate_Struct {
/*00*/ uint32 unknown00; //seems to be a value from AA_Action.ability
@@ -3913,7 +3935,7 @@ struct AltAdvStats_Struct {
};
struct PlayerAA_Struct { // Is this still used?
AA_Skills aa_list[MAX_PP_AA_ARRAY];
AA_Array aa_list[MAX_PP_AA_ARRAY];
};
struct AATable_Struct {
@@ -3923,7 +3945,7 @@ struct AATable_Struct {
/*12*/ int32 unknown012;
/*16*/ int32 unknown016;
/*20*/ int32 unknown020;
/*24*/ AA_Skills aa_list[MAX_PP_AA_ARRAY];
/*24*/ AA_Array aa_list[MAX_PP_AA_ARRAY];
};
struct Weather_Struct {
+3 -6
View File
@@ -47,7 +47,6 @@ const ProcLauncher::ProcRef ProcLauncher::ProcError = -1;
ProcLauncher::ProcLauncher()
{
_eqp
#ifndef WIN32
if(signal(SIGCHLD, ProcLauncher::HandleSigChild) == SIG_ERR)
fprintf(stderr, "Unable to register child signal handler. Thats bad.");
@@ -56,7 +55,6 @@ ProcLauncher::ProcLauncher()
}
void ProcLauncher::Process() {
_eqp
#ifdef _WINDOWS
std::map<ProcRef, Spec *>::iterator cur, end, tmp;
cur = m_running.begin();
@@ -110,7 +108,7 @@ void ProcLauncher::Process() {
}
void ProcLauncher::ProcessTerminated(std::map<ProcRef, Spec *>::iterator &it) {
_eqp
if(it->second->handler != nullptr)
it->second->handler->OnTerminate(it->first, it->second);
@@ -123,7 +121,6 @@ void ProcLauncher::ProcessTerminated(std::map<ProcRef, Spec *>::iterator &it) {
}
ProcLauncher::ProcRef ProcLauncher::Launch(Spec *&to_launch) {
_eqp
//consume the pointer
Spec *it = to_launch;
to_launch = nullptr;
@@ -278,7 +275,6 @@ ProcLauncher::ProcRef ProcLauncher::Launch(Spec *&to_launch) {
//if graceful is true, we try to be nice about it if possible
bool ProcLauncher::Terminate(const ProcRef &proc, bool graceful) {
_eqp
//we are only willing to kill things we started...
std::map<ProcRef, Spec *>::iterator res = m_running.find(proc);
if(res == m_running.end())
@@ -305,7 +301,6 @@ bool ProcLauncher::Terminate(const ProcRef &proc, bool graceful) {
}
void ProcLauncher::TerminateAll(bool final) {
_eqp
if(!final) {
//send a nice terminate to each process, with intention of waiting for them
std::map<ProcRef, Spec *>::iterator cur, end;
@@ -338,6 +333,8 @@ void ProcLauncher::HandleSigChild(int signum) {
}
#endif
ProcLauncher::Spec::Spec() {
handler = nullptr;
}
+92
View File
@@ -0,0 +1,92 @@
/* EQEMu: Everquest Server Emulator
Copyright (C) 2001-2004 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 PROFILER_H
#define PROFILER_H
#ifdef EQPROFILE
#include "../common/rdtsc.h"
#include "../common/types.h"
class ScopedProfiler;
class GeneralProfiler {
friend class ScopedProfiler;
public:
inline GeneralProfiler(unsigned int _count) {
count = _count;
timers = new RDTSC_Collector[count];
}
inline virtual ~GeneralProfiler() {
safe_delete_array(timers);
}
inline double getTotalDuration(unsigned int id) {
return(id<count? timers[id].getTotalDuration() : 0);
}
inline double getAverage(unsigned int id) {
return(id<count? timers[id].getAverage() : 0);
}
inline unsigned long long getTicks(unsigned int id) {
return(id<count? timers[id].getTicks() : 0);
}
inline unsigned long long getTotalTicks(unsigned int id) {
return(id<count? timers[id].getTotalTicks() : 0);
}
inline unsigned long long getCount(unsigned int id) {
return(id<count? timers[id].getCount() : 0);
}
inline void reset() {
unsigned int r;
RDTSC_Collector *cur = timers;
for(r = 0; r < count; r++, cur++)
cur->reset();
}
RDTSC_Collector *timers;
unsigned int count;
};
class ScopedProfiler {
public:
inline ScopedProfiler(RDTSC_Collector *c) {
_it = c;
c->start();
}
inline ~ScopedProfiler() {
_it->stop();
}
protected:
RDTSC_Collector *_it;
};
#define _GP(obj, pkg, name) ScopedProfiler __eqemu_profiler(&obj.timers[pkg::name])
#else // else !EQPROFILE
//no profiling, dummy functions
#define _GP(obj, pkg, name) ;
#endif
#endif
+3
View File
@@ -175,6 +175,7 @@ bool PersistentTimer::Store(Database *db) {
}
bool PersistentTimer::Clear(Database *db) {
std::string query = StringFormat("DELETE FROM timers "
"WHERE char_id = %lu AND type = %u ",
(unsigned long)_char_id, _type);
@@ -415,6 +416,7 @@ PersistentTimer *PTimerList::Get(pTimerType type) {
}
void PTimerList::ToVector(std::vector< std::pair<pTimerType, PersistentTimer *> > &out) {
std::pair<pTimerType, PersistentTimer *> p;
std::map<pTimerType, PersistentTimer *>::iterator s;
@@ -430,6 +432,7 @@ void PTimerList::ToVector(std::vector< std::pair<pTimerType, PersistentTimer *>
}
bool PTimerList::ClearOffline(Database *db, uint32 char_id, pTimerType type) {
std::string query = StringFormat("DELETE FROM timers WHERE char_id=%lu AND type=%u ",(unsigned long)char_id, type);
#ifdef DEBUG_PTIMERS
+2 -1
View File
@@ -39,7 +39,8 @@ enum { //values for pTimerType
pTimerDisciplineReuseStart = 14,
pTimerDisciplineReuseEnd = 24,
pTimerCombatAbility = 25,
pTimerBeggingPickPocket = 26,
pTimerCombatAbility2 = 26, // RoF2+ Tiger Claw is unlinked from other monk skills, generic in case other classes ever need it
pTimerBeggingPickPocket = 27,
pTimerLayHands = 87, //these IDs are used by client too
pTimerHarmTouch = 89, //so dont change them
+2
View File
@@ -47,6 +47,8 @@
#define IKSAR 128
#define VAHSHIR 130
#define CONTROLLED_BOAT 141
#define MINOR_ILL_OBJ 142
#define TREE 143
#define IKSAR_SKELETON 161
#define FROGLOK 330
#define FROGLOK2 74 // Not sure why /who all reports race as 74 for frogloks
+167
View File
@@ -0,0 +1,167 @@
/* EQEMu: Everquest Server Emulator
Copyright (C) 2001-2006 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 "rdtsc.h"
#include "types.h"
#ifdef _WINDOWS
#include <sys/timeb.h>
#include "../common/timer.h"
#else
#include <unistd.h>
#include <sys/time.h>
#endif
#ifdef i386
#define USE_RDTSC
#endif
bool RDTSC_Timer::_inited = false;
int64 RDTSC_Timer::_ticsperms = 0;
RDTSC_Timer::RDTSC_Timer() {
if(!_inited) {
//find our clock rate
RDTSC_Timer::init();
}
_start = 0;
_end = 0;
}
RDTSC_Timer::RDTSC_Timer(bool start_it) {
if(!_inited) {
//find our clock rate
RDTSC_Timer::init();
}
if(start_it)
start();
else {
_start = 0;
_end = 0;
}
}
int64 RDTSC_Timer::rdtsc() {
int64 res = 0;
#ifdef USE_RDTSC
#ifndef WIN64
#ifdef WIN32
//untested!
unsigned long highw, loww;
__asm {
push eax
push edx
rdtsc
mov highw, eax
mov loww, edx
pop edx
pop eax
}
res = ((int64)highw)<<32 | loww;
#else
//gnu version
__asm__ __volatile__ ("rdtsc" : "=A" (res));
#endif
#else
//fall back to get time of day
timeval t;
gettimeofday(&t, nullptr);
res = ((int64)t.tv_sec) * 1000 + t.tv_usec;
#endif
#endif
return(res);
}
void RDTSC_Timer::init() {
#ifdef USE_RDTSC
int64 before, after, sum;
int r;
sum = 0;
// run an average to increase accuracy of clock rate
for(r = 0; r < CALIBRATE_LOOPS; r++) {
before = rdtsc();
//sleep a know duration to figure out clock rate
#ifdef _WINDOWS
Sleep(SLEEP_TIME);
#else
usleep(SLEEP_TIME * 1000); //ms * 1000
#endif
after = rdtsc();
sum += after - before;
}
//ticks per sleep / ms per sleep
_ticsperms = (sum / CALIBRATE_LOOPS) / SLEEP_TIME;
#else
//if using gettimeofday, this is fixed at 1000
_ticsperms = 1000;
#endif
// printf("Tics per milisecond: %llu \n", _ticsperms);
_inited = true; //only want to do this once
}
//start the timer
void RDTSC_Timer::start() {
_start = rdtsc();
_end = 0;
}
//stop the timer
void RDTSC_Timer::stop() {
_end = rdtsc();
}
//calculate the elapsed duration
double RDTSC_Timer::getDuration() {
return(((double)(getTicks())) / double(_ticsperms));
}
RDTSC_Collector::RDTSC_Collector() : RDTSC_Timer() {
reset();
}
RDTSC_Collector::RDTSC_Collector(bool start_it) : RDTSC_Timer(start_it) {
reset();
}
void RDTSC_Collector::stop() {
RDTSC_Timer::stop();
_sum += RDTSC_Timer::getTicks();
_count++;
}
//calculate the elapsed duration
double RDTSC_Collector::getTotalDuration() {
return(((double)(getTotalTicks())) / double(_ticsperms));
}
double RDTSC_Collector::getAverage() {
return(((double)(getTotalTicks())) / double(_ticsperms * _count));
}
void RDTSC_Collector::reset() {
_sum = 0;
_count = 0;
}
+86
View File
@@ -0,0 +1,86 @@
/* EQEMu: Everquest Server Emulator
Copyright (C) 2001-2006 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 RDTSC_H
#define RDTSC_H
#define CALIBRATE_LOOPS 3
#define SLEEP_TIME 10 //in ms
/*
This class implementes the highest possibly prescision timer
which is avaliable on the current archetecture.
On intel, this uses the rdtsc instruction to get the actual
clock cycle count, and elsewhere it falls back to gettimeofday
All calculations are carried out in 64 bit integers.
*/
#include "types.h"
class RDTSC_Timer {
public:
RDTSC_Timer();
RDTSC_Timer(bool start_it);
void start(); //start the timer
virtual void stop(); //stop the timer
double getDuration(); //returns the number of miliseconds elapsed
//access functions
int64 getTicks() { return(_end - _start); }
static int64 ticksPerMS() { return(_ticsperms); }
protected:
static int64 rdtsc();
int64 _start;
int64 _end;
protected:
static void init();
static bool _inited;
static int64 _ticsperms;
};
//this is a timer which can be started and stoped many times.
//each time it contributes its counter to a sum, whic is used
//to find net duration.
class RDTSC_Collector : public RDTSC_Timer {
public:
RDTSC_Collector();
RDTSC_Collector(bool start_it);
void reset();
void stop(); //stop the timer
double getTotalDuration(); //returns the number of miliseconds elapsed
double getAverage();
int64 getTotalTicks() { return(_sum); }
int64 getCount() { return(_count); }
protected:
int64 _sum;
int64 _count;
};
#endif
+518 -497
View File
File diff suppressed because it is too large Load Diff
+18
View File
@@ -153,6 +153,8 @@
#define ServerOP_GetWorldTime 0x200C
#define ServerOP_SyncWorldTime 0x200E
#define ServerOP_ClientFileStatus 0x2020
#define ServerOP_LSZoneInfo 0x3001
#define ServerOP_LSZoneStart 0x3002
#define ServerOP_LSZoneBoot 0x3003
@@ -1263,6 +1265,22 @@ struct ServerRequestTellQueue_Struct {
char name[64];
};
struct ServerRequestClientFileStatus
{
int zone_id;
int instance_id;
char name[64];
};
struct ServerResponseClientFileStatus
{
char name[64];
bool spells;
bool skills;
bool base_data;
bool eqgame;
};
#pragma pack()
#endif
+22 -71
View File
@@ -43,7 +43,6 @@ SharedDatabase::~SharedDatabase() {
bool SharedDatabase::SetHideMe(uint32 account_id, uint8 hideme)
{
_eqp
std::string query = StringFormat("UPDATE account SET hideme = %i WHERE id = %i", hideme, account_id);
auto results = QueryDatabase(query);
if (!results.Success()) {
@@ -55,7 +54,6 @@ bool SharedDatabase::SetHideMe(uint32 account_id, uint8 hideme)
uint8 SharedDatabase::GetGMSpeed(uint32 account_id)
{
_eqp
std::string query = StringFormat("SELECT gmspeed FROM account WHERE id = '%i'", account_id);
auto results = QueryDatabase(query);
if (!results.Success()) {
@@ -72,7 +70,6 @@ uint8 SharedDatabase::GetGMSpeed(uint32 account_id)
bool SharedDatabase::SetGMSpeed(uint32 account_id, uint8 gmspeed)
{
_eqp
std::string query = StringFormat("UPDATE account SET gmspeed = %i WHERE id = %i", gmspeed, account_id);
auto results = QueryDatabase(query);
if (!results.Success()) {
@@ -83,7 +80,6 @@ bool SharedDatabase::SetGMSpeed(uint32 account_id, uint8 gmspeed)
}
uint32 SharedDatabase::GetTotalTimeEntitledOnAccount(uint32 AccountID) {
_eqp
uint32 EntitledTime = 0;
std::string query = StringFormat("SELECT `time_played` FROM `character_data` WHERE `account_id` = %u", AccountID);
auto results = QueryDatabase(query);
@@ -95,7 +91,6 @@ uint32 SharedDatabase::GetTotalTimeEntitledOnAccount(uint32 AccountID) {
bool SharedDatabase::SaveCursor(uint32 char_id, std::list<ItemInst*>::const_iterator &start, std::list<ItemInst*>::const_iterator &end)
{
_eqp
// Delete cursor items
std::string query = StringFormat("DELETE FROM inventory WHERE charid = %i "
"AND ((slotid >= 8000 AND slotid <= 8999) "
@@ -123,7 +118,6 @@ bool SharedDatabase::SaveCursor(uint32 char_id, std::list<ItemInst*>::const_iter
bool SharedDatabase::VerifyInventory(uint32 account_id, int16 slot_id, const ItemInst* inst)
{
_eqp
// Delete cursor items
std::string query = StringFormat("SELECT itemid, charges FROM sharedbank "
"WHERE acctid = %d AND slotid = %d",
@@ -156,13 +150,6 @@ bool SharedDatabase::VerifyInventory(uint32 account_id, int16 slot_id, const Ite
}
bool SharedDatabase::SaveInventory(uint32 char_id, const ItemInst* inst, int16 slot_id) {
_eqp
// If we never save tribute slots..how are we to ever benefit from them!!? The client
// object is destroyed upon zoning - including its inventory object..and if tributes
// don't exist in the database, then they will never be loaded when the new client
// object is created in the new zone object... Something to consider... -U
//
// (we could add them to the 'NoRent' checks and dispose of after 30 minutes offline)
//never save tribute slots:
if(slot_id >= EmuConstants::TRIBUTE_BEGIN && slot_id <= EmuConstants::TRIBUTE_END)
@@ -170,20 +157,29 @@ bool SharedDatabase::SaveInventory(uint32 char_id, const ItemInst* inst, int16 s
if (slot_id >= EmuConstants::SHARED_BANK_BEGIN && slot_id <= EmuConstants::SHARED_BANK_BAGS_END) {
// Shared bank inventory
if (!inst)
return DeleteSharedBankSlot(char_id, slot_id);
else
return UpdateSharedBankSlot(char_id, inst, slot_id);
if (!inst) {
return DeleteSharedBankSlot(char_id, slot_id);
}
else {
// Needed to clear out bag slots that 'REPLACE' in UpdateSharedBankSlot does not overwrite..otherwise, duplication occurs
// (This requires that parent then child items be sent..which should be how they are currently passed)
if (Inventory::SupportsContainers(slot_id))
DeleteSharedBankSlot(char_id, slot_id);
return UpdateSharedBankSlot(char_id, inst, slot_id);
}
}
else if (!inst) { // All other inventory
return DeleteInventorySlot(char_id, slot_id);
}
// Needed to clear out bag slots that 'REPLACE' in UpdateInventorySlot does not overwrite..otherwise, duplication occurs
// (This requires that parent then child items be sent..which should be how they are currently passed)
if (Inventory::SupportsContainers(slot_id))
DeleteInventorySlot(char_id, slot_id);
return UpdateInventorySlot(char_id, inst, slot_id);
}
bool SharedDatabase::UpdateInventorySlot(uint32 char_id, const ItemInst* inst, int16 slot_id) {
_eqp
// need to check 'inst' argument for valid pointer
uint32 augslot[EmuConstants::ITEM_COMMON_SIZE] = { NO_ITEM, NO_ITEM, NO_ITEM, NO_ITEM, NO_ITEM, NO_ITEM };
@@ -216,7 +212,9 @@ bool SharedDatabase::UpdateInventorySlot(uint32 char_id, const ItemInst* inst, i
// Save bag contents, if slot supports bag contents
if (inst->IsType(ItemClassContainer) && Inventory::SupportsContainers(slot_id))
for (uint8 idx = SUB_BEGIN; idx < EmuConstants::ITEM_CONTAINER_SIZE; idx++) {
// Limiting to bag slot count will get rid of 'hidden' duplicated items and 'Invalid Slot ID'
// messages through attrition (and the modded code in SaveInventory)
for (uint8 idx = SUB_BEGIN; idx < inst->GetItem()->BagSlots && idx < EmuConstants::ITEM_CONTAINER_SIZE; idx++) {
const ItemInst* baginst = inst->GetItem(idx);
SaveInventory(char_id, baginst, Inventory::CalcSlotId(slot_id, idx));
}
@@ -229,7 +227,6 @@ bool SharedDatabase::UpdateInventorySlot(uint32 char_id, const ItemInst* inst, i
}
bool SharedDatabase::UpdateSharedBankSlot(uint32 char_id, const ItemInst* inst, int16 slot_id) {
_eqp
// need to check 'inst' argument for valid pointer
uint32 augslot[EmuConstants::ITEM_COMMON_SIZE] = { NO_ITEM, NO_ITEM, NO_ITEM, NO_ITEM, NO_ITEM, NO_ITEM };
@@ -261,7 +258,9 @@ bool SharedDatabase::UpdateSharedBankSlot(uint32 char_id, const ItemInst* inst,
// Save bag contents, if slot supports bag contents
if (inst->IsType(ItemClassContainer) && Inventory::SupportsContainers(slot_id)) {
for (uint8 idx = SUB_BEGIN; idx < EmuConstants::ITEM_CONTAINER_SIZE; idx++) {
// Limiting to bag slot count will get rid of 'hidden' duplicated items and 'Invalid Slot ID'
// messages through attrition (and the modded code in SaveInventory)
for (uint8 idx = SUB_BEGIN; idx < inst->GetItem()->BagSlots && idx < EmuConstants::ITEM_CONTAINER_SIZE; idx++) {
const ItemInst* baginst = inst->GetItem(idx);
SaveInventory(char_id, baginst, Inventory::CalcSlotId(slot_id, idx));
}
@@ -275,7 +274,6 @@ bool SharedDatabase::UpdateSharedBankSlot(uint32 char_id, const ItemInst* inst,
}
bool SharedDatabase::DeleteInventorySlot(uint32 char_id, int16 slot_id) {
_eqp
// Delete item
std::string query = StringFormat("DELETE FROM inventory WHERE charid = %i AND slotid = %i", char_id, slot_id);
@@ -301,7 +299,6 @@ bool SharedDatabase::DeleteInventorySlot(uint32 char_id, int16 slot_id) {
}
bool SharedDatabase::DeleteSharedBankSlot(uint32 char_id, int16 slot_id) {
_eqp
// Delete item
uint32 account_id = GetAccountIDByChar(char_id);
@@ -331,7 +328,6 @@ bool SharedDatabase::DeleteSharedBankSlot(uint32 char_id, int16 slot_id) {
int32 SharedDatabase::GetSharedPlatinum(uint32 account_id)
{
_eqp
std::string query = StringFormat("SELECT sharedplat FROM account WHERE id = '%i'", account_id);
auto results = QueryDatabase(query);
if (!results.Success()) {
@@ -347,7 +343,6 @@ int32 SharedDatabase::GetSharedPlatinum(uint32 account_id)
}
bool SharedDatabase::SetSharedPlatinum(uint32 account_id, int32 amount_to_add) {
_eqp
std::string query = StringFormat("UPDATE account SET sharedplat = sharedplat + %i WHERE id = %i", amount_to_add, account_id);
auto results = QueryDatabase(query);
if (!results.Success()) {
@@ -358,7 +353,7 @@ bool SharedDatabase::SetSharedPlatinum(uint32 account_id, int32 amount_to_add) {
}
bool SharedDatabase::SetStartingItems(PlayerProfile_Struct* pp, Inventory* inv, uint32 si_race, uint32 si_class, uint32 si_deity, uint32 si_current_zone, char* si_name, int admin_level) {
_eqp
const Item_Struct* myitem;
std::string query = StringFormat("SELECT itemid, item_charges, slot FROM starting_items "
@@ -396,7 +391,6 @@ bool SharedDatabase::SetStartingItems(PlayerProfile_Struct* pp, Inventory* inv,
// Retrieve shared bank inventory based on either account or character
bool SharedDatabase::GetSharedBank(uint32 id, Inventory *inv, bool is_charid)
{
_eqp
std::string query;
if (is_charid)
@@ -497,7 +491,6 @@ bool SharedDatabase::GetSharedBank(uint32 id, Inventory *inv, bool is_charid)
// Overloaded: Retrieve character inventory based on character id
bool SharedDatabase::GetInventory(uint32 char_id, Inventory *inv)
{
_eqp
// Retrieve character inventory
std::string query =
StringFormat("SELECT slotid, itemid, charges, color, augslot1, augslot2, augslot3, augslot4, augslot5, "
@@ -641,7 +634,6 @@ bool SharedDatabase::GetInventory(uint32 char_id, Inventory *inv)
// Overloaded: Retrieve character inventory based on account_id and character name
bool SharedDatabase::GetInventory(uint32 account_id, char *name, Inventory *inv)
{
_eqp
// Retrieve character inventory
std::string query =
StringFormat("SELECT slotid, itemid, charges, color, augslot1, "
@@ -751,7 +743,6 @@ bool SharedDatabase::GetInventory(uint32 account_id, char *name, Inventory *inv)
std::map<uint32, uint32> SharedDatabase::GetItemRecastTimestamps(uint32 char_id)
{
_eqp
std::map<uint32, uint32> timers;
std::string query = StringFormat("SELECT recast_type,timestamp FROM character_item_recast WHERE id=%u", char_id);
auto results = QueryDatabase(query);
@@ -765,7 +756,6 @@ std::map<uint32, uint32> SharedDatabase::GetItemRecastTimestamps(uint32 char_id)
uint32 SharedDatabase::GetItemRecastTimestamp(uint32 char_id, uint32 recast_type)
{
_eqp
std::string query = StringFormat("SELECT timestamp FROM character_item_recast WHERE id=%u AND recast_type=%u",
char_id, recast_type);
auto results = QueryDatabase(query);
@@ -778,7 +768,6 @@ uint32 SharedDatabase::GetItemRecastTimestamp(uint32 char_id, uint32 recast_type
void SharedDatabase::ClearOldRecastTimestamps(uint32 char_id)
{
_eqp
// This actually isn't strictly live-like. Live your recast timestamps are forever
std::string query =
StringFormat("DELETE FROM character_item_recast WHERE id = %u and timestamp < UNIX_TIMESTAMP()", char_id);
@@ -787,7 +776,6 @@ void SharedDatabase::ClearOldRecastTimestamps(uint32 char_id)
void SharedDatabase::GetItemsCount(int32 &item_count, uint32 &max_id)
{
_eqp
item_count = -1;
max_id = 0;
@@ -810,7 +798,6 @@ void SharedDatabase::GetItemsCount(int32 &item_count, uint32 &max_id)
}
bool SharedDatabase::LoadItems() {
_eqp
if(items_mmf) {
return true;
}
@@ -842,7 +829,6 @@ bool SharedDatabase::LoadItems() {
}
void SharedDatabase::LoadItems(void *data, uint32 size, int32 items, uint32 max_item_id) {
_eqp
EQEmu::FixedMemoryHashSet<Item_Struct> hash(reinterpret_cast<uint8*>(data), size, items, max_item_id);
char ndbuffer[4];
@@ -1100,7 +1086,6 @@ void SharedDatabase::LoadItems(void *data, uint32 size, int32 items, uint32 max_
}
const Item_Struct* SharedDatabase::GetItem(uint32 id) {
_eqp
if (id == 0)
{
return nullptr;
@@ -1120,7 +1105,6 @@ const Item_Struct* SharedDatabase::GetItem(uint32 id) {
}
const Item_Struct* SharedDatabase::IterateItems(uint32* id) {
_eqp
if(!items_hash || !id) {
return nullptr;
}
@@ -1142,7 +1126,6 @@ const Item_Struct* SharedDatabase::IterateItems(uint32* id) {
std::string SharedDatabase::GetBook(const char *txtfile)
{
_eqp
char txtfile2[20];
std::string txtout;
strcpy(txtfile2, txtfile);
@@ -1167,7 +1150,6 @@ std::string SharedDatabase::GetBook(const char *txtfile)
}
void SharedDatabase::GetFactionListInfo(uint32 &list_count, uint32 &max_lists) {
_eqp
list_count = 0;
max_lists = 0;
@@ -1187,7 +1169,6 @@ void SharedDatabase::GetFactionListInfo(uint32 &list_count, uint32 &max_lists) {
}
const NPCFactionList* SharedDatabase::GetNPCFactionEntry(uint32 id) {
_eqp
if(!faction_hash) {
return nullptr;
}
@@ -1200,7 +1181,6 @@ const NPCFactionList* SharedDatabase::GetNPCFactionEntry(uint32 id) {
}
void SharedDatabase::LoadNPCFactionLists(void *data, uint32 size, uint32 list_count, uint32 max_lists) {
_eqp
EQEmu::FixedMemoryHashSet<NPCFactionList> hash(reinterpret_cast<uint8*>(data), size, list_count, max_lists);
NPCFactionList faction;
@@ -1250,7 +1230,6 @@ void SharedDatabase::LoadNPCFactionLists(void *data, uint32 size, uint32 list_co
}
bool SharedDatabase::LoadNPCFactionLists() {
_eqp
if(faction_hash) {
return true;
}
@@ -1283,7 +1262,6 @@ bool SharedDatabase::LoadNPCFactionLists() {
// Create appropriate ItemInst class
ItemInst* SharedDatabase::CreateItem(uint32 item_id, int16 charges, uint32 aug1, uint32 aug2, uint32 aug3, uint32 aug4, uint32 aug5, uint32 aug6, uint8 attuned)
{
_eqp
const Item_Struct* item = nullptr;
ItemInst* inst = nullptr;
@@ -1313,7 +1291,6 @@ ItemInst* SharedDatabase::CreateItem(uint32 item_id, int16 charges, uint32 aug1,
// Create appropriate ItemInst class
ItemInst* SharedDatabase::CreateItem(const Item_Struct* item, int16 charges, uint32 aug1, uint32 aug2, uint32 aug3, uint32 aug4, uint32 aug5, uint32 aug6, uint8 attuned)
{
_eqp
ItemInst* inst = nullptr;
if (item) {
inst = CreateBaseItem(item, charges);
@@ -1337,7 +1314,6 @@ ItemInst* SharedDatabase::CreateItem(const Item_Struct* item, int16 charges, uin
}
ItemInst* SharedDatabase::CreateBaseItem(const Item_Struct* item, int16 charges) {
_eqp
ItemInst* inst = nullptr;
if (item) {
// if maxcharges is -1 that means it is an unlimited use item.
@@ -1364,7 +1340,6 @@ ItemInst* SharedDatabase::CreateBaseItem(const Item_Struct* item, int16 charges)
}
int32 SharedDatabase::DeleteStalePlayerCorpses() {
_eqp
if(RuleB(Zone, EnableShadowrest)) {
std::string query = StringFormat(
"UPDATE `character_corpses` SET `is_buried` = 1 WHERE `is_buried` = 0 AND "
@@ -1387,8 +1362,7 @@ int32 SharedDatabase::DeleteStalePlayerCorpses() {
return results.RowsAffected();
}
bool SharedDatabase::GetCommandSettings(std::map<std::string, uint8> &commands) {
_eqp
bool SharedDatabase::GetCommandSettings(std::map<std::string,uint8> &commands) {
const std::string query = "SELECT command, access FROM commands";
auto results = QueryDatabase(query);
@@ -1405,7 +1379,6 @@ bool SharedDatabase::GetCommandSettings(std::map<std::string, uint8> &commands)
}
bool SharedDatabase::LoadSkillCaps() {
_eqp
if(skill_caps_mmf)
return true;
@@ -1432,7 +1405,6 @@ bool SharedDatabase::LoadSkillCaps() {
}
void SharedDatabase::LoadSkillCaps(void *data) {
_eqp
uint32 class_count = PLAYER_CLASS_COUNT;
uint32 skill_count = HIGHEST_SKILL + 1;
uint32 level_count = HARD_LEVEL_CAP + 1;
@@ -1460,7 +1432,6 @@ void SharedDatabase::LoadSkillCaps(void *data) {
}
uint16 SharedDatabase::GetSkillCap(uint8 Class_, SkillUseTypes Skill, uint8 Level) {
_eqp
if(!skill_caps_mmf) {
return 0;
}
@@ -1490,7 +1461,6 @@ uint16 SharedDatabase::GetSkillCap(uint8 Class_, SkillUseTypes Skill, uint8 Leve
}
uint8 SharedDatabase::GetTrainLevel(uint8 Class_, SkillUseTypes Skill, uint8 Level) {
_eqp
if(!skill_caps_mmf) {
return 0;
}
@@ -1540,7 +1510,6 @@ uint8 SharedDatabase::GetTrainLevel(uint8 Class_, SkillUseTypes Skill, uint8 Lev
}
void SharedDatabase::LoadDamageShieldTypes(SPDat_Spell_Struct* sp, int32 iMaxSpellID) {
_eqp
std::string query = StringFormat("SELECT `spellid`, `type` FROM `damageshieldtypes` WHERE `spellid` > 0 "
"AND `spellid` <= %i", iMaxSpellID);
@@ -1558,12 +1527,10 @@ void SharedDatabase::LoadDamageShieldTypes(SPDat_Spell_Struct* sp, int32 iMaxSpe
}
const EvolveInfo* SharedDatabase::GetEvolveInfo(uint32 loregroup) {
_eqp
return nullptr; // nothing here for now... database and/or sharemem pulls later
}
int SharedDatabase::GetMaxSpellID() {
_eqp
std::string query = "SELECT MAX(id) FROM spells_new";
auto results = QueryDatabase(query);
if (!results.Success()) {
@@ -1576,7 +1543,6 @@ int SharedDatabase::GetMaxSpellID() {
}
void SharedDatabase::LoadSpells(void *data, int max_spells) {
_eqp
SPDat_Spell_Struct *sp = reinterpret_cast<SPDat_Spell_Struct*>(data);
const std::string query = "SELECT * FROM spells_new ORDER BY id ASC";
@@ -1739,7 +1705,6 @@ void SharedDatabase::LoadSpells(void *data, int max_spells) {
}
int SharedDatabase::GetMaxBaseDataLevel() {
_eqp
const std::string query = "SELECT MAX(level) FROM base_data";
auto results = QueryDatabase(query);
if (!results.Success()) {
@@ -1755,7 +1720,6 @@ int SharedDatabase::GetMaxBaseDataLevel() {
}
bool SharedDatabase::LoadBaseData() {
_eqp
if(base_data_mmf) {
return true;
}
@@ -1784,7 +1748,6 @@ bool SharedDatabase::LoadBaseData() {
}
void SharedDatabase::LoadBaseData(void *data, int max_level) {
_eqp
char *base_ptr = reinterpret_cast<char*>(data);
const std::string query = "SELECT * FROM base_data ORDER BY level, class ASC";
@@ -1834,7 +1797,6 @@ void SharedDatabase::LoadBaseData(void *data, int max_level) {
}
const BaseDataStruct* SharedDatabase::GetBaseData(int lvl, int cl) {
_eqp
if(!base_data_mmf) {
return nullptr;
}
@@ -1864,7 +1826,6 @@ const BaseDataStruct* SharedDatabase::GetBaseData(int lvl, int cl) {
}
void SharedDatabase::GetLootTableInfo(uint32 &loot_table_count, uint32 &max_loot_table, uint32 &loot_table_entries) {
_eqp
loot_table_count = 0;
max_loot_table = 0;
loot_table_entries = 0;
@@ -1885,7 +1846,6 @@ void SharedDatabase::GetLootTableInfo(uint32 &loot_table_count, uint32 &max_loot
}
void SharedDatabase::GetLootDropInfo(uint32 &loot_drop_count, uint32 &max_loot_drop, uint32 &loot_drop_entries) {
_eqp
loot_drop_count = 0;
max_loot_drop = 0;
loot_drop_entries = 0;
@@ -1907,7 +1867,6 @@ void SharedDatabase::GetLootDropInfo(uint32 &loot_drop_count, uint32 &max_loot_d
}
void SharedDatabase::LoadLootTables(void *data, uint32 size) {
_eqp
EQEmu::FixedMemoryVariableHashSet<LootTable_Struct> hash(reinterpret_cast<uint8*>(data), size);
uint8 loot_table[sizeof(LootTable_Struct) + (sizeof(LootTableEntries_Struct) * 128)];
@@ -1961,7 +1920,6 @@ void SharedDatabase::LoadLootTables(void *data, uint32 size) {
}
void SharedDatabase::LoadLootDrops(void *data, uint32 size) {
_eqp
EQEmu::FixedMemoryVariableHashSet<LootDrop_Struct> hash(reinterpret_cast<uint8*>(data), size);
uint8 loot_drop[sizeof(LootDrop_Struct) + (sizeof(LootDropEntries_Struct) * 1260)];
@@ -2010,7 +1968,6 @@ void SharedDatabase::LoadLootDrops(void *data, uint32 size) {
}
bool SharedDatabase::LoadLoot() {
_eqp
if(loot_table_mmf || loot_drop_mmf)
return true;
@@ -2035,7 +1992,6 @@ bool SharedDatabase::LoadLoot() {
}
const LootTable_Struct* SharedDatabase::GetLootTable(uint32 loottable_id) {
_eqp
if(!loot_table_hash)
return nullptr;
@@ -2050,7 +2006,6 @@ const LootTable_Struct* SharedDatabase::GetLootTable(uint32 loottable_id) {
}
const LootDrop_Struct* SharedDatabase::GetLootDrop(uint32 lootdrop_id) {
_eqp
if(!loot_drop_hash)
return nullptr;
@@ -2065,7 +2020,6 @@ const LootDrop_Struct* SharedDatabase::GetLootDrop(uint32 lootdrop_id) {
}
void SharedDatabase::LoadCharacterInspectMessage(uint32 character_id, InspectMessage_Struct* message) {
_eqp
std::string query = StringFormat("SELECT `inspect_message` FROM `character_inspect_messages` WHERE `id` = %u LIMIT 1", character_id);
auto results = QueryDatabase(query);
auto row = results.begin();
@@ -2076,13 +2030,11 @@ void SharedDatabase::LoadCharacterInspectMessage(uint32 character_id, InspectMes
}
void SharedDatabase::SaveCharacterInspectMessage(uint32 character_id, const InspectMessage_Struct* message) {
_eqp
std::string query = StringFormat("REPLACE INTO `character_inspect_messages` (id, inspect_message) VALUES (%u, '%s')", character_id, EscapeString(message->text).c_str());
auto results = QueryDatabase(query);
}
void SharedDatabase::GetBotInspectMessage(uint32 botid, InspectMessage_Struct* message) {
_eqp
std::string query = StringFormat("SELECT BotInspectMessage FROM bots WHERE BotID = %i", botid);
auto results = QueryDatabase(query);
@@ -2099,7 +2051,6 @@ void SharedDatabase::GetBotInspectMessage(uint32 botid, InspectMessage_Struct* m
}
void SharedDatabase::SetBotInspectMessage(uint32 botid, const InspectMessage_Struct* message) {
_eqp
std::string msg = EscapeString(message->text);
std::string query = StringFormat("UPDATE bots SET BotInspectMessage = '%s' WHERE BotID = %i", msg.c_str(), botid);
QueryDatabase(query);
+51
View File
@@ -55,3 +55,54 @@ bool EQEmu::IsSpecializedSkill(SkillUseTypes skill)
return false;
}
}
float EQEmu::GetSkillMeleePushForce(SkillUseTypes skill)
{
// This is the force/magnitude of the push from an attack of this skill type
// You can find these numbers in the clients skill struct
switch (skill) {
case Skill1HBlunt:
case Skill1HSlashing:
case SkillHandtoHand:
case SkillThrowing:
return 0.1f;
case Skill2HBlunt:
case Skill2HSlashing:
case SkillEagleStrike:
case SkillKick:
case SkillTigerClaw:
//case Skill2HPiercing:
return 0.2f;
case SkillArchery:
return 0.15f;
case SkillBackstab:
case SkillBash:
return 0.3f;
case SkillDragonPunch:
case SkillRoundKick:
return 0.25f;
case SkillFlyingKick:
return 0.4f;
case Skill1HPiercing:
case SkillFrenzy:
return 0.05f;
case SkillIntimidation:
return 2.5f;
default:
return 0.0f;
}
}
bool EQEmu::IsBardInstrumentSkill(SkillUseTypes skill)
{
switch (skill) {
case SkillBrassInstruments:
case SkillSinging:
case SkillStringedInstruments:
case SkillWindInstruments:
case SkillPercussionInstruments:
return true;
default:
return false;
}
}
+4
View File
@@ -171,6 +171,8 @@ enum SkillUseTypes
// temporary until it can be sorted out...
#define HIGHEST_SKILL SkillFrenzy
// Spell Effects use this value to determine if an effect applies to all skills.
#define ALL_SKILLS -1
// server profile does not reflect this yet..so, prefixed with 'PACKET_'
#define PACKET_SKILL_ARRAY_SIZE 100
@@ -268,6 +270,8 @@ typedef enum {
namespace EQEmu {
bool IsTradeskill(SkillUseTypes skill);
bool IsSpecializedSkill(SkillUseTypes skill);
float GetSkillMeleePushForce(SkillUseTypes skill);
bool IsBardInstrumentSkill(SkillUseTypes skill);
}
#endif
+7 -7
View File
@@ -72,7 +72,7 @@
#include "../common/eqemu_logsys.h"
#include "../common/eqemu_logsys.h"
#include "classes.h"
#include "spdat.h"
@@ -162,7 +162,7 @@ bool IsCureSpell(uint16 spell_id)
bool CureEffect = false;
for(int i = 0; i < EFFECT_COUNT; i++){
if (sp.effectid[i] == SE_DiseaseCounter || sp.effectid[i] == SE_PoisonCounter
if (sp.effectid[i] == SE_DiseaseCounter || sp.effectid[i] == SE_PoisonCounter
|| sp.effectid[i] == SE_CurseCounter || sp.effectid[i] == SE_CorruptionCounter)
CureEffect = true;
}
@@ -405,7 +405,7 @@ bool IsPartialCapableSpell(uint16 spell_id)
{
if (spells[spell_id].no_partial_resist)
return false;
if (IsPureNukeSpell(spell_id))
return true;
@@ -447,7 +447,7 @@ bool IsTGBCompatibleSpell(uint16 spell_id)
bool IsBardSong(uint16 spell_id)
{
if (IsValidSpell(spell_id) && spells[spell_id].classes[BARD - 1] < 255)
if (IsValidSpell(spell_id) && spells[spell_id].classes[BARD - 1] < 255 && !spells[spell_id].IsDisciplineBuff)
return true;
return false;
@@ -693,9 +693,9 @@ bool IsCombatSkill(uint16 spell_id)
{
if (!IsValidSpell(spell_id))
return false;
//Check if Discipline
if ((spells[spell_id].mana == 0 && (spells[spell_id].EndurCost || spells[spell_id].EndurUpkeep)))
if ((spells[spell_id].mana == 0 && (spells[spell_id].EndurCost || spells[spell_id].EndurUpkeep)))
return true;
return false;
@@ -1040,7 +1040,7 @@ bool IsCastonFadeDurationSpell(uint16 spell_id)
bool IsPowerDistModSpell(uint16 spell_id)
{
if (IsValidSpell(spell_id) &&
if (IsValidSpell(spell_id) &&
(spells[spell_id].max_dist_mod || spells[spell_id].min_dist_mod) && spells[spell_id].max_dist > spells[spell_id].min_dist)
return true;
+19 -17
View File
@@ -38,6 +38,7 @@
#define MAX_RESISTABLE_EFFECTS 12 // Number of effects that are typcially checked agianst resists.
#define MaxLimitInclude 16 //Number(x 0.5) of focus Limiters that have inclusive checks used when calcing focus effects
#define MAX_SKILL_PROCS 4 //Number of spells to check skill procs from. (This is arbitrary) [Single spell can have multiple proc checks]
#define MAX_SYMPATHETIC_PROCS 10 // Number of sympathetic procs a client can have (This is arbitrary)
const int Z_AGGRO=10;
@@ -132,7 +133,7 @@ typedef enum {
/* 42 */ ST_Directional = 0x2a, //ae around this target between two angles
/* 43 */ ST_GroupClientAndPet = 0x2b,
/* 44 */ ST_Beam = 0x2c,
/* 45 */ ST_Ring = 0x2d,
/* 45 */ ST_Ring = 0x2d,
/* 46 */ ST_TargetsTarget = 0x2e, // uses the target of your target
/* 47 */ ST_PetMaster = 0x2f, // uses the master as target
/* 48 */ // UNKNOWN
@@ -150,10 +151,10 @@ typedef enum {
} DmgShieldType;
//Spell Effect IDs
// full listing: https://forums.station.sony.com/eq/index.php?threads/enumerated-spa-list.206288/
// https://forums.daybreakgames.com/eq/index.php?threads/enumerated-spa-list.206288/
// mirror: http://pastebin.com/MYeQqGwe
#define SE_CurrentHP 0 // implemented - Heals and nukes, repeates every tic if in a buff
#define SE_ArmorClass 1 // implemented
#define SE_ArmorClass 1 // implemented
#define SE_ATK 2 // implemented
#define SE_MovementSpeed 3 // implemented - SoW, SoC, etc
#define SE_STR 4 // implemented
@@ -196,7 +197,7 @@ typedef enum {
#define SE_Destroy 41 // implemented - Disintegrate, Banishment of Shadows
#define SE_ShadowStep 42 // implemented
#define SE_Berserk 43 // implemented (*not used in any known live spell) Makes client 'Berserk' giving crip blow chance.
#define SE_Lycanthropy 44 // implemented
#define SE_Lycanthropy 44 // implemented
#define SE_Vampirism 45 // implemented (*not used in any known live spell) Stackable lifetap from melee.
#define SE_ResistFire 46 // implemented
#define SE_ResistCold 47 // implemented
@@ -246,7 +247,7 @@ typedef enum {
#define SE_SummonCorpse 91 // implemented
#define SE_InstantHate 92 // implemented - add hate
#define SE_StopRain 93 // implemented - Wake of Karana
#define SE_NegateIfCombat 94 // implemented
#define SE_NegateIfCombat 94 // implemented
#define SE_Sacrifice 95 // implemented
#define SE_Silence 96 // implemented
#define SE_ManaPool 97 // implemented
@@ -298,7 +299,7 @@ typedef enum {
#define SE_LimitCastTimeMin 143 // implemented
#define SE_LimitCastTimeMax 144 // implemented (*not used in any known live spell)
#define SE_Teleport2 145 // implemented - Banishment of the Pantheon
//#define SE_ElectricityResist 146 // *not implemented (Lightning Rod: 23233)
//#define SE_ElectricityResist 146 // *not implemented (Lightning Rod: 23233)
#define SE_PercentalHeal 147 // implemented
#define SE_StackingCommand_Block 148 // implemented?
#define SE_StackingCommand_Overwrite 149 // implemented?
@@ -528,7 +529,7 @@ typedef enum {
#define SE_CastOnFadeEffectAlways 373 // implemented - Triggers if fades after natural duration OR from rune/numhits fades.
#define SE_ApplyEffect 374 // implemented
#define SE_DotCritDmgIncrease 375 // implemented - Increase damage of DoT critical amount
//#define SE_Fling 376 // *not implemented - used in 2 test spells (12945 | Movement Test Spell 1)
//#define SE_Fling 376 // *not implemented - used in 2 test spells (12945 | Movement Test Spell 1)
#define SE_CastOnFadeEffectNPC 377 // implemented - Triggers only if fades after natural duration (On live these are usually players spells that effect an NPC).
#define SE_SpellEffectResistChance 378 // implemented - Increase chance to resist specific spell effect (base1=value, base2=spell effect id)
#define SE_ShadowStepDirectional 379 // implemented - handled by client
@@ -559,7 +560,7 @@ typedef enum {
#define SE_LimitSpellSubclass 404 // *not implemented - Limits to specific types of spells (see CheckSpellCategory) [Categories NOT defined yet]
#define SE_TwoHandBluntBlock 405 // implemented - chance to block attacks when using two hand blunt weapons (similiar to shield block)
#define SE_CastonNumHitFade 406 // implemented - casts a spell when a buff fades due to its numhits being depleted
#define SE_CastonFocusEffect 407 // implemented - casts a spell if focus limits are met (ie triggers when a focus effects is applied)
#define SE_CastonFocusEffect 407 // implemented - casts a spell if focus limits are met (ie triggers when a focus effects is applied)
#define SE_LimitHPPercent 408 // implemented - limited to a certain percent of your hp(ie heals up to 50%)
#define SE_LimitManaPercent 409 // implemented - limited to a certain percent of your mana
#define SE_LimitEndPercent 410 // implemented - limited to a certain percent of your end
@@ -575,7 +576,7 @@ typedef enum {
#define SE_FcLimitUse 420 // implemented - increases numhits count by percent (Note: not used in any known live spells)
#define SE_FcIncreaseNumHits 421 // implemented[AA] - increases number of hits a buff has till fade. (focus)
#define SE_LimitUseMin 422 // implemented - limit a focus to require a min amount of numhits value (used with above)
#define SE_LimitUseType 423 // implemented - limit a focus to require a certain numhits type
#define SE_LimitUseType 423 // implemented - limit a focus to require a certain numhits type
#define SE_GravityEffect 424 // implemented - Pulls/pushes you toward/away the mob at a set pace
//#define SE_Display 425 // *not implemented - Illusion: Flying Dragon(21626)
//#define SE_IncreaseExtTargetWindow 426 // *not implmented[AA] - increases the capacity of your extended target window
@@ -599,9 +600,9 @@ typedef enum {
#define SE_ImprovedTaunt 444 // implemented - Locks Aggro On Caster and Decrease other Players Aggro by X% on NPC targets below level Y
//#define SE_AddMercSlot 445 // *not implemented[AA] - [Hero's Barracks] Allows you to conscript additional mercs.
#define SE_AStacker 446 // implementet - bufff stacking blocker (26219 | Qirik's Watch)
#define SE_BStacker 447 // implemented
#define SE_BStacker 447 // implemented
#define SE_CStacker 448 // implemented
#define SE_DStacker 449 // implemented
#define SE_DStacker 449 // implemented
#define SE_MitigateDotDamage 450 // implemented DOT spell mitigation rune with max value
#define SE_MeleeThresholdGuard 451 // implemented Partial Melee Rune that only is lowered if melee hits are over X amount of damage
#define SE_SpellThresholdGuard 452 // implemented Partial Spell Rune that only is lowered if spell hits are over X amount of damage
@@ -617,6 +618,7 @@ typedef enum {
#define DF_Permanent 50
#define DF_Aura 51
// note this struct is historical, we don't actually need it to be
// aligned to anything, but for maintaining it it is kept in the order that
@@ -732,31 +734,31 @@ struct SPDat_Spell_Struct
/* 197 */ bool not_extendable;
/* 198- 199 */
/* 200 */ bool suspendable; // buff is suspended in suspended buff zones
/* 201 */ int viral_range;
/* 201 */ int viral_range;
/* 202 */
/* 203 */ //int songcap; // individual song cap (how live currently does it, not implemented)
/* 204 */
/* 205 */ bool no_block;
/* 206 */
/* 206 */
/* 207 */ int spellgroup;
/* 208 */ int rank; //increments AA effects with same name
/* 209 */ int powerful_flag; // Need more investigation to figure out what to call this, for now we know -1 makes charm spells not break before their duration is complete, it does alot more though
/* 210 */ // bool DurationFrozen; ???
/* 210 */ // bool DurationFrozen; ???
/* 211 */ int CastRestriction; //Various restriction categories for spells most seem targetable race related but have also seen others for instance only castable if target hp 20% or lower or only if target out of combat
/* 212 */ bool AllowRest;
/* 213 */ bool InCombat; //Allow spell if target is in combat
/* 214 */ bool OutofCombat; //Allow spell if target is out of combat
/* 215 - 217 */
/* 218 */ int aemaxtargets; //Is used for various AE effects
/* 218 */ int aemaxtargets; //Is used for various AE effects
/* 219 */ int maxtargets; //Is used for beam and ring spells for target # limits (not implemented)
/* 220 - 223 */
/* 220 - 223 */
/* 224 */ bool persistdeath; // buff doesn't get stripped on death
/* 225 - 226 */
/* 227 */ float min_dist; //spell power modified by distance from caster (Min Distance)
/* 228 */ float min_dist_mod; //spell power modified by distance from caster (Modifier at Min Distance)
/* 229 */ float max_dist; //spell power modified by distance from caster (Max Distance)
/* 230 */ float max_dist_mod; //spell power modified by distance from caster (Modifier at Max Distance)
/* 231 */ float min_range; //Min casting range
/* 231 */ float min_range; //Min casting range
/* 232 - 236 */
uint8 DamageShieldType; // This field does not exist in spells_us.txt
};
-7
View File
@@ -64,7 +64,6 @@ const std::string vStringFormat(const char* format, va_list args)
const std::string StringFormat(const char* format, ...)
{
_eqp
va_list args;
va_start(args, format);
std::string output = vStringFormat(format,args);
@@ -122,7 +121,6 @@ void MakeLowerString(const char *source, char *target) {
}
int MakeAnyLenString(char** ret, const char* format, ...) {
_eqp
int buf_len = 128;
int chars = -1;
va_list argptr, tmpargptr;
@@ -142,7 +140,6 @@ int MakeAnyLenString(char** ret, const char* format, ...) {
}
uint32 AppendAnyLenString(char** ret, uint32* bufsize, uint32* strlen, const char* format, ...) {
_eqp
if (*bufsize == 0)
*bufsize = 256;
if (*ret == 0)
@@ -261,7 +258,6 @@ bool atobool(const char* iBool) {
// removes the crap and turns the underscores into spaces.
char *CleanMobName(const char *in, char *out)
{
_eqp
unsigned i, j;
for(i = j = 0; i < strlen(in); i++)
@@ -316,7 +312,6 @@ const char *ConvertArrayF(float input, char *returnchar)
}
std::vector<std::string> SplitString(const std::string &str, char delim) {
_eqp
std::vector<std::string> ret;
std::stringstream ss(str);
std::string item;
@@ -329,7 +324,6 @@ std::vector<std::string> SplitString(const std::string &str, char delim) {
}
std::string EscapeString(const std::string &s) {
_eqp
std::string ret;
size_t sz = s.length();
@@ -367,7 +361,6 @@ std::string EscapeString(const std::string &s) {
}
std::string EscapeString(const char *src, size_t sz) {
_eqp
std::string ret;
for(size_t i = 0; i < sz; ++i) {
-8
View File
@@ -11,7 +11,6 @@
//note: all encoders and decoders must be valid functions.
//so if you specify set_defaults=false
StructStrategy::StructStrategy() {
_eqp
int r;
for(r = 0; r < _maxEmuOpcode; r++) {
encoders[r] = PassEncoder;
@@ -20,7 +19,6 @@ StructStrategy::StructStrategy() {
}
void StructStrategy::Encode(EQApplicationPacket **p, std::shared_ptr<EQStream> dest, bool ack_req) const {
_eqp
if((*p)->GetOpcodeBypass() != 0) {
PassEncoder(p, dest, ack_req);
return;
@@ -32,7 +30,6 @@ void StructStrategy::Encode(EQApplicationPacket **p, std::shared_ptr<EQStream> d
}
void StructStrategy::Decode(EQApplicationPacket *p) const {
_eqp
EmuOpcode op = p->GetOpcode();
Decoder proc = decoders[op];
proc(p);
@@ -40,7 +37,6 @@ void StructStrategy::Decode(EQApplicationPacket *p) const {
void StructStrategy::ErrorEncoder(EQApplicationPacket **in_p, std::shared_ptr<EQStream> dest, bool ack_req) {
_eqp
EQApplicationPacket *p = *in_p;
*in_p = nullptr;
@@ -50,13 +46,11 @@ void StructStrategy::ErrorEncoder(EQApplicationPacket **in_p, std::shared_ptr<EQ
}
void StructStrategy::ErrorDecoder(EQApplicationPacket *p) {
_eqp
Log.Out(Logs::General, Logs::Netcode, "[STRUCTS] Error decoding opcode %s: no decoder provided. Invalidating.", OpcodeManager::EmuToName(p->GetOpcode()));
p->SetOpcode(OP_Unknown);
}
void StructStrategy::PassEncoder(EQApplicationPacket **p, std::shared_ptr<EQStream> dest, bool ack_req) {
_eqp
dest->FastQueuePacket(p, ack_req);
}
@@ -73,12 +67,10 @@ namespace StructStrategyFactory {
static std::map<EmuOpcode, const StructStrategy *> strategies;
void RegisterPatch(EmuOpcode first_opcode, const StructStrategy *structs) {
_eqp
strategies[first_opcode] = structs;
}
const StructStrategy *FindPatch(EmuOpcode first_opcode) {
_eqp
std::map<EmuOpcode, const StructStrategy *>::const_iterator res;
res = strategies.find(first_opcode);
if(res == strategies.end())
-33
View File
@@ -75,7 +75,6 @@ TCPConnection::TCPConnection(uint32 ID, SOCKET in_socket, uint32 irIP, uint16 ir
rIP(irIP),
rPort(irPort)
{
_eqp
pState = TCPS_Connected;
pFree = false;
pEcho = false;
@@ -91,7 +90,6 @@ TCPConnection::TCPConnection(uint32 ID, SOCKET in_socket, uint32 irIP, uint16 ir
}
TCPConnection::~TCPConnection() {
_eqp
FinishDisconnect();
ClearBuffers();
if (ConnectionType == Outgoing) {
@@ -115,14 +113,12 @@ TCPConnection::~TCPConnection() {
}
void TCPConnection::SetState(State_t in_state) {
_eqp
MState.lock();
pState = in_state;
MState.unlock();
}
TCPConnection::State_t TCPConnection::GetState() const {
_eqp
State_t ret;
MState.lock();
ret = pState;
@@ -132,7 +128,6 @@ TCPConnection::State_t TCPConnection::GetState() const {
bool TCPConnection::GetSockName(char *host, uint16 *port)
{
_eqp
bool result=false;
LockMutex lock(&MState);
if (!Connected())
@@ -170,13 +165,11 @@ bool TCPConnection::GetSockName(char *host, uint16 *port)
}
void TCPConnection::Free() {
_eqp
Disconnect();
pFree = true;
}
bool TCPConnection::Send(const uchar* data, int32 size) {
_eqp
if (!Connected())
return false;
if (!size)
@@ -186,7 +179,6 @@ bool TCPConnection::Send(const uchar* data, int32 size) {
}
void TCPConnection::ServerSendQueuePushEnd(const uchar* data, int32 size) {
_eqp
MSendQueue.lock();
if (sendbuf == nullptr) {
sendbuf = new uchar[size];
@@ -206,7 +198,6 @@ void TCPConnection::ServerSendQueuePushEnd(const uchar* data, int32 size) {
}
void TCPConnection::ServerSendQueuePushEnd(uchar** data, int32 size) {
_eqp
MSendQueue.lock();
if (sendbuf == 0) {
sendbuf = *data;
@@ -230,7 +221,6 @@ void TCPConnection::ServerSendQueuePushEnd(uchar** data, int32 size) {
}
void TCPConnection::ServerSendQueuePushFront(uchar* data, int32 size) {
_eqp
MSendQueue.lock();
if (sendbuf == 0) {
sendbuf = new uchar[size];
@@ -250,7 +240,6 @@ void TCPConnection::ServerSendQueuePushFront(uchar* data, int32 size) {
}
bool TCPConnection::ServerSendQueuePop(uchar** data, int32* size) {
_eqp
bool ret;
if (!MSendQueue.trylock())
return false;
@@ -268,7 +257,6 @@ bool TCPConnection::ServerSendQueuePop(uchar** data, int32* size) {
}
bool TCPConnection::ServerSendQueuePopForce(uchar** data, int32* size) {
_eqp
bool ret;
MSendQueue.lock();
if (sendbuf) {
@@ -285,7 +273,6 @@ bool TCPConnection::ServerSendQueuePopForce(uchar** data, int32* size) {
}
char* TCPConnection::PopLine() {
_eqp
char* ret;
if (!MLineOutQueue.trylock())
return 0;
@@ -295,7 +282,6 @@ char* TCPConnection::PopLine() {
}
bool TCPConnection::LineOutQueuePush(char* line) {
_eqp
MLineOutQueue.lock();
LineOutQueue.push(line);
MLineOutQueue.unlock();
@@ -304,7 +290,6 @@ bool TCPConnection::LineOutQueuePush(char* line) {
void TCPConnection::FinishDisconnect() {
_eqp
MState.lock();
if (connection_socket != INVALID_SOCKET && connection_socket != 0) {
if (pState == TCPS_Connected || pState == TCPS_Disconnecting || pState == TCPS_Disconnected) {
@@ -329,7 +314,6 @@ void TCPConnection::FinishDisconnect() {
}
void TCPConnection::Disconnect() {
_eqp
MState.lock();
if(pState == TCPS_Connected || pState == TCPS_Connecting) {
pState = TCPS_Disconnecting;
@@ -338,7 +322,6 @@ void TCPConnection::Disconnect() {
}
bool TCPConnection::GetAsyncConnect() {
_eqp
bool ret;
MAsyncConnect.lock();
ret = pAsyncConnect;
@@ -347,7 +330,6 @@ bool TCPConnection::GetAsyncConnect() {
}
bool TCPConnection::SetAsyncConnect(bool iValue) {
_eqp
bool ret;
MAsyncConnect.lock();
ret = pAsyncConnect;
@@ -357,7 +339,6 @@ bool TCPConnection::SetAsyncConnect(bool iValue) {
}
bool TCPConnection::ConnectReady() const {
_eqp
State_t s = GetState();
if (s != TCPS_Ready && s != TCPS_Disconnected)
return(false);
@@ -365,7 +346,6 @@ bool TCPConnection::ConnectReady() const {
}
void TCPConnection::AsyncConnect(const char* irAddress, uint16 irPort) {
_eqp
safe_delete_array(charAsyncConnect);
charAsyncConnect = new char[strlen(irAddress) + 1];
strcpy(charAsyncConnect, irAddress);
@@ -373,7 +353,6 @@ void TCPConnection::AsyncConnect(const char* irAddress, uint16 irPort) {
}
void TCPConnection::AsyncConnect(uint32 irIP, uint16 irPort) {
_eqp
if (ConnectionType != Outgoing) {
// If this code runs, we got serious problems
// Crash and burn.
@@ -415,7 +394,6 @@ void TCPConnection::AsyncConnect(uint32 irIP, uint16 irPort) {
}
bool TCPConnection::Connect(const char* irAddress, uint16 irPort, char* errbuf) {
_eqp
if (errbuf)
errbuf[0] = 0;
uint32 tmpIP = ResolveIP(irAddress);
@@ -433,7 +411,6 @@ bool TCPConnection::Connect(const char* irAddress, uint16 irPort, char* errbuf)
}
bool TCPConnection::ConnectIP(uint32 in_ip, uint16 in_port, char* errbuf) {
_eqp
if (errbuf)
errbuf[0] = 0;
if (ConnectionType != Outgoing) {
@@ -522,7 +499,6 @@ bool TCPConnection::ConnectIP(uint32 in_ip, uint16 in_port, char* errbuf) {
}
void TCPConnection::ClearBuffers() {
_eqp
LockMutex lock1(&MSendQueue);
LockMutex lock3(&MRunLoop);
LockMutex lock4(&MState);
@@ -535,7 +511,6 @@ void TCPConnection::ClearBuffers() {
}
bool TCPConnection::CheckNetActive() {
_eqp
MState.lock();
if (pState == TCPS_Connected || pState == TCPS_Disconnecting) {
MState.unlock();
@@ -548,7 +523,6 @@ bool TCPConnection::CheckNetActive() {
/* This is always called from an IO thread. Either the server socket's thread, or a
* special thread we create when we make an outbound connection. */
bool TCPConnection::Process() {
_eqp
char errbuf[TCPConnection_ErrorBufferSize];
switch(GetState()) {
case TCPS_Ready:
@@ -620,7 +594,6 @@ bool TCPConnection::Process() {
}
bool TCPConnection::RecvData(char* errbuf) {
_eqp
if (errbuf)
errbuf[0] = 0;
if (!Connected()) {
@@ -693,19 +666,16 @@ bool TCPConnection::RecvData(char* errbuf) {
bool TCPConnection::GetEcho() {
_eqp
bool ret;
ret = pEcho;
return ret;
}
void TCPConnection::SetEcho(bool iValue) {
_eqp
pEcho = iValue;
}
bool TCPConnection::ProcessReceivedData(char* errbuf) {
_eqp
if (errbuf)
errbuf[0] = 0;
if (!recvbuf)
@@ -840,7 +810,6 @@ bool TCPConnection::ProcessReceivedData(char* errbuf) {
}
bool TCPConnection::SendData(bool &sent_something, char* errbuf) {
_eqp
if (errbuf)
errbuf[0] = 0;
/************ Get first send packet on queue and send it! ************/
@@ -922,7 +891,6 @@ bool TCPConnection::SendData(bool &sent_something, char* errbuf) {
}
ThreadReturnType TCPConnection::TCPConnectionLoop(void* tmp) {
_eqp
#ifdef _WINDOWS
SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_ABOVE_NORMAL);
#endif
@@ -965,7 +933,6 @@ ThreadReturnType TCPConnection::TCPConnectionLoop(void* tmp) {
}
bool TCPConnection::RunLoop() {
_eqp
bool ret;
MRunLoop.lock();
ret = pRunLoop;
+3 -9
View File
@@ -24,22 +24,18 @@
Timeoutable::Timeoutable(uint32 check_frequency)
: next_check(check_frequency)
{
_eqp
timeout_manager.AddMember(this);
}
Timeoutable::~Timeoutable() {
_eqp
timeout_manager.DeleteMember(this);
}
TimeoutManager::TimeoutManager() {
_eqp
}
void TimeoutManager::CheckTimeouts() {
_eqp
std::vector<Timeoutable *>::iterator cur,end;
cur = members.begin();
end = members.end();
@@ -47,7 +43,7 @@ void TimeoutManager::CheckTimeouts() {
Timeoutable *it = *cur;
if(it->next_check.Check()) {
#ifdef TIMEOUT_DEBUG
Log.Out(Logs::General, Logs::None, "Checking timeout on 0x%x\n", it);
Log.Out(Logs::General, Logs::None,, "Checking timeout on 0x%x\n", it);
#endif
it->CheckTimeout();
}
@@ -56,21 +52,19 @@ void TimeoutManager::CheckTimeouts() {
//methods called by Timeoutable objects:
void TimeoutManager::AddMember(Timeoutable *who) {
_eqp
if(who == nullptr)
return;
DeleteMember(who); //just in case... prolly not needed.
members.push_back(who);
#ifdef TIMEOUT_DEBUG
Log.Out(Logs::General, Logs::None, "Adding timeoutable 0x%x\n", who);
Log.Out(Logs::General, Logs::None,, "Adding timeoutable 0x%x\n", who);
#endif
}
void TimeoutManager::DeleteMember(Timeoutable *who) {
_eqp
#ifdef TIMEOUT_DEBUG
Log.Out(Logs::General, Logs::None, "Removing timeoutable 0x%x\n", who);
Log.Out(Logs::General, Logs::None,, "Removing timeoutable 0x%x\n", who);
#endif
std::vector<Timeoutable *>::iterator cur,end;
cur = members.begin();
-1
View File
@@ -81,7 +81,6 @@ int gettimeofday (timeval *tp, ...)
/* This function checks if the timer triggered */
bool Timer::Check(bool iReset)
{
_eqp
if (enabled && current_time-start_time > timer_time) {
if (iReset) {
if (pUseAcurateTiming)
+16 -1
View File
@@ -18,7 +18,6 @@
#ifndef TYPES_H
#define TYPES_H
#include <eqp_profiler.h>
#include <stdint.h>
typedef uint8_t byte;
typedef uint8_t uint8;
@@ -84,4 +83,20 @@ typedef const char Const_char; //for perl XS
#define DLLFUNC extern "C"
#endif
// htonll and ntohll already defined on windows
#ifndef WIN32
# if defined(__linux__)
# include <endian.h>
# elif defined(__FreeBSD__) || defined(__NetBSD__)
# include <sys/endian.h>
# elif defined (__OpenBSD__)
# include <sys/types.h>
# define be16toh(x) betoh16(x)
# define be32toh(x) betoh32(x)
# define be64toh(x) betoh64(x)
# endif
# define htonll(x) htobe64(x)
# define ntohll(x) be64toh(x)
#endif
#endif
-44
View File
@@ -1,44 +0,0 @@
/*
EQEMu: Everquest Server Emulator
Copyright (C) 2001-2014 EQEMu Development Team (http://eqemulator.net)
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY except by those people which sell it, which
are required to give you total support for your newly bought product;
without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "uuid.h"
#ifdef WIN32
#include <rpc.h>
#else
#include <uuid/uuid.h>
#endif
std::string CreateUUID() {
#ifdef WIN32
UUID uuid;
UuidCreate(&uuid);
unsigned char *str = nullptr;
UuidToStringA(&uuid, &str);
std::string s((char*)str);
RpcStringFreeA(&str);
return s;
#else
char str[64] = { 0 };
uuid_t uuid;
uuid_generate_random(uuid);
uuid_unparse(uuid, str);
return str;
#endif
}
-26
View File
@@ -1,26 +0,0 @@
/*
EQEMu: Everquest Server Emulator
Copyright (C) 2001-2014 EQEMu Development Team (http://eqemulator.net)
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY except by those people which sell it, which
are required to give you total support for your newly bought product;
without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef COMMON_UUID_H
#define COMMON_UUID_H
#include <string>
std::string CreateUUID();
#endif
+4 -4
View File
@@ -24,13 +24,13 @@
#define CURRENT_VERSION "1.1.3"
/*
Everytime a Database SQL is added to Github,
/*
Everytime a Database SQL is added to Github,
increment CURRENT_BINARY_DATABASE_VERSION number and make sure you update the manifest
Manifest: https://github.com/EQEmu/Server/blob/master/utils/sql/db_update_manifest.txt
Manifest: https://github.com/EQEmu/Server/blob/master/utils/sql/db_update_manifest.txt
*/
#define CURRENT_BINARY_DATABASE_VERSION 9076
#define CURRENT_BINARY_DATABASE_VERSION 9083
#define COMPILE_DATE __DATE__
#define COMPILE_TIME __TIME__
#ifndef WIN32
-8
View File
@@ -28,25 +28,21 @@
WorldConnection::WorldConnection(EmuTCPConnection::ePacketMode mode, const char *password)
: m_password(password)
{
_eqp
tcpc.SetPacketMode(mode);
pTryReconnect = true;
pConnected = false;
}
WorldConnection::~WorldConnection() {
_eqp
}
bool WorldConnection::SendPacket(ServerPacket* pack) {
_eqp
if (!Connected())
return false;
return tcpc.SendPacket(pack);
}
void WorldConnection::OnConnected() {
_eqp
const EQEmuConfig *Config=EQEmuConfig::get();
Log.Out(Logs::General, Logs::Netcode, "[WORLD] Connected to World: %s:%d", Config->WorldIP.c_str(), Config->WorldTCPPort);
@@ -57,7 +53,6 @@ void WorldConnection::OnConnected() {
}
void WorldConnection::Process() {
_eqp
//persistent connection....
if (!Connected()) {
pConnected = tcpc.Connected();
@@ -71,13 +66,11 @@ void WorldConnection::Process() {
}
void WorldConnection::AsyncConnect() {
_eqp
const EQEmuConfig *Config=EQEmuConfig::get();
tcpc.AsyncConnect(Config->WorldIP.c_str(), Config->WorldTCPPort);
}
bool WorldConnection::Connect() {
_eqp
const EQEmuConfig *Config=EQEmuConfig::get();
char errbuf[TCPConnection_ErrorBufferSize];
if (tcpc.Connect(Config->WorldIP.c_str(), Config->WorldTCPPort, errbuf)) {
@@ -89,7 +82,6 @@ bool WorldConnection::Connect() {
}
void WorldConnection::Disconnect() {
_eqp
tcpc.Disconnect();
}
-3
View File
@@ -23,7 +23,6 @@ XMLParser::XMLParser() {
}
bool XMLParser::ParseFile(const char *file, const char *root_ele) {
_eqp
std::map<std::string,ElementHandler>::iterator handler;
TiXmlDocument doc( file );
if(!doc.LoadFile()) {
@@ -71,7 +70,6 @@ bool XMLParser::ParseFile(const char *file, const char *root_ele) {
}
const char *XMLParser::ParseTextBlock(TiXmlNode *within, const char *name, bool optional) {
_eqp
TiXmlElement * txt = within->FirstChildElement(name);
if(txt == nullptr) {
if(!optional) {
@@ -90,7 +88,6 @@ const char *XMLParser::ParseTextBlock(TiXmlNode *within, const char *name, bool
}
const char *XMLParser::GetText(TiXmlNode *within, bool optional) {
_eqp
TiXmlNode *contents = within->FirstChild();
if(contents == nullptr || contents->Type() != TiXmlNode::TEXT) {
if(!optional) {
+1 -4
View File
@@ -15,17 +15,15 @@ ADD_EXECUTABLE(eqlaunch ${eqlaunch_sources} ${eqlaunch_headers})
INSTALL(TARGETS eqlaunch RUNTIME DESTINATION ${CMAKE_INSTALL_PREFIX})
TARGET_LINK_LIBRARIES(eqlaunch common ${PERF_LIBS} debug ${MySQL_LIBRARY_DEBUG} optimized ${MySQL_LIBRARY_RELEASE} ${ZLIB_LIBRARY})
TARGET_LINK_LIBRARIES(eqlaunch common debug ${MySQL_LIBRARY_DEBUG} optimized ${MySQL_LIBRARY_RELEASE} ${ZLIB_LIBRARY})
IF(MSVC)
SET_TARGET_PROPERTIES(eqlaunch PROPERTIES LINK_FLAGS_RELEASE "/OPT:REF /OPT:ICF")
TARGET_LINK_LIBRARIES(eqlaunch "Ws2_32.lib")
TARGET_LINK_LIBRARIES(eqlaunch "rpcrt4")
ENDIF(MSVC)
IF(MINGW)
TARGET_LINK_LIBRARIES(eqlaunch "WS2_32")
TARGET_LINK_LIBRARIES(eqlaunch "rpcrt4")
ENDIF(MINGW)
IF(UNIX)
@@ -36,7 +34,6 @@ IF(UNIX)
TARGET_LINK_LIBRARIES(eqlaunch "rt")
ENDIF(NOT DARWIN)
TARGET_LINK_LIBRARIES(eqlaunch "pthread")
TARGET_LINK_LIBRARIES(eqlaunch "uuid")
ADD_DEFINITIONS(-fPIC)
ENDIF(UNIX)
-6
View File
@@ -69,10 +69,6 @@ int main(int argc, char *argv[]) {
Log.Out(Logs::Detail, Logs::Launcher, "Could not set signal handler");
return 1;
}
if (signal(SIGBREAK, CatchSignal) == SIG_ERR) {
Log.Out(Logs::Detail, Logs::Launcher, "Could not set signal handler");
return 1;
}
#ifndef WIN32
if (signal(SIGPIPE, SIG_IGN) == SIG_ERR) {
Log.Out(Logs::Detail, Logs::Launcher, "Could not set signal handler");
@@ -190,8 +186,6 @@ int main(int argc, char *argv[]) {
void CatchSignal(int sig_num) {
Log.Out(Logs::Detail, Logs::Launcher, "Caught signal %d", sig_num);
RunLoops = false;
_eqp_dump_file("eqlaunch");
}
-20
View File
@@ -1,20 +0,0 @@
CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
SET(eqperf_sources
eqp_profile_event.cpp
eqp_profile_timer.cpp
eqp_profiler.cpp
eqp_profiler_node.cpp
)
SET(eqperf_headers
eqp_profile_event.h
eqp_profile_function.h
eqp_profile_timer.h
eqp_profiler.h
eqp_profiler_node.h
)
ADD_LIBRARY(eqperf ${eqperf_sources} ${eqperf_headers})
SET(LIBRARY_OUTPUT_PATH ${PROJECT_BINARY_DIR}/bin)
-47
View File
@@ -1,47 +0,0 @@
#include "eqp_profile_event.h"
#include "eqp_profile_timer.h"
#include "eqp_profiler.h"
EQP::CPU::ST::Event::Event(const char *function_name) {
function_name_ = function_name;
name_ = nullptr;
start_ = GetCurrentTimer();
identifier_ = EQP::CPU::ST::GetProfiler().EventStarted(function_name_, name_);
}
EQP::CPU::ST::Event::Event(const char *function_name, const char *name) {
function_name_ = function_name;
name_ = name;
start_ = GetCurrentTimer();
identifier_ = EQP::CPU::ST::GetProfiler().EventStarted(function_name_, name_);
}
EQP::CPU::ST::Event::~Event() {
uint64_t end = GetCurrentTimer();
EQP::CPU::ST::GetProfiler().EventFinished(end - start_, identifier_);
}
EQP::CPU::MT::Event::Event(const char *function_name) {
function_name_ = function_name;
name_ = nullptr;
start_ = GetCurrentTimer();
identifier_ = EQP::CPU::MT::GetProfiler().EventStarted(function_name_, name_);
}
EQP::CPU::MT::Event::Event(const char *function_name, const char *name) {
function_name_ = function_name;
name_ = name;
start_ = GetCurrentTimer();
identifier_ = EQP::CPU::MT::GetProfiler().EventStarted(function_name_, name_);
}
EQP::CPU::MT::Event::~Event() {
uint64_t end = GetCurrentTimer();
EQP::CPU::MT::GetProfiler().EventFinished(end - start_, identifier_);
}
-44
View File
@@ -1,44 +0,0 @@
#pragma once
#include <string>
#include <stdint.h>
#include "eqp_profile_function.h"
namespace EQP
{
namespace CPU
{
namespace ST
{
class EQP_EXPORT Event
{
public:
Event(const char *function_name);
Event(const char *function_name, const char *name);
~Event();
private:
const char *function_name_;
const char *name_;
uint64_t start_;
std::string identifier_;
};
}
namespace MT
{
class EQP_EXPORT Event
{
public:
Event(const char *function_name);
Event(const char *function_name, const char *name);
~Event();
private:
const char *function_name_;
const char *name_;
uint64_t start_;
std::string identifier_;
};
}
}
} // Profile
-16
View File
@@ -1,16 +0,0 @@
#pragma once
#ifndef __PRETTY_FUNCTION__
#ifdef _MSC_VER
#define __PRETTY_FUNCTION__ __FUNCSIG__
#else
#define __PRETTY_FUNCTION__ __FUNCTION__
#endif
#endif
#ifdef _MSC_VER
//#define EQP_EXPORT __declspec(dllexport)
#define EQP_EXPORT
#else
#define EQP_EXPORT
#endif
-24
View File
@@ -1,24 +0,0 @@
#include "eqp_profile_timer.h"
#ifdef _MSC_VER
#include <Windows.h>
#else
#include <time.h>
#endif
uint64_t EQP::GetCurrentTimer()
{
#ifdef _MSC_VER
LARGE_INTEGER qpt_i;
QueryPerformanceCounter(&qpt_i);
return qpt_i.QuadPart;
#else
timespec tp;
if(clock_gettime(CLOCK_MONOTONIC, &tp) == 0) {
uint64_t res = tp.tv_sec * 1000000000;
res += tp.tv_nsec;
return res;
}
return 0;
#endif
}
-9
View File
@@ -1,9 +0,0 @@
#pragma once
#include <stdint.h>
namespace EQP
{
uint64_t GetCurrentTimer();
} // EQP
-245
View File
@@ -1,245 +0,0 @@
#include "eqp_profiler.h"
#include "eqp_profile_timer.h"
#include <iostream>
#include <thread>
#include <mutex>
#include <vector>
#include <algorithm>
#include "../common/uuid.h"
struct EQP::CPU::MT::Profiler::impl
{
std::mutex lock_;
std::unordered_map<std::thread::id, ThreadInfo*> nodes_;
std::string identifier_;
};
EQP::CPU::ST::Profiler &EQP::CPU::ST::GetProfiler() {
static EQP::CPU::ST::Profiler st_profiler;
return st_profiler;
}
EQP::CPU::MT::Profiler &EQP::CPU::MT::GetProfiler() {
static EQP::CPU::MT::Profiler mt_profiler;
return mt_profiler;
}
EQP::CPU::ST::Profiler::Profiler() {
root_ = new ProfilerNode;
root_->SetParent(root_);
current_ = root_;
identifier_ = CreateUUID();
}
EQP::CPU::ST::Profiler::~Profiler() {
delete root_;
}
std::string EQP::CPU::ST::Profiler::EventStarted(const char *func, const char *name) {
std::string cur_name = func;
if(name) {
cur_name += " - ";
cur_name += name;
}
auto search = current_->GetNodes().find(cur_name);
if(search != current_->GetNodes().end()) {
current_ = search->second;
} else {
ProfilerNode *t = new ProfilerNode;
t->SetParent(current_);
current_->GetNodes()[cur_name] = t;
current_ = t;
}
current_->GetCount()++;
current_->SetStarted(GetCurrentTimer());
return identifier_;
}
void EQP::CPU::ST::Profiler::EventFinished(uint64_t time, std::string ident) {
if(ident.compare(identifier_) != 0) {
return;
}
current_->SetStarted(0);
current_->GetTime() += time;
current_ = current_->GetParent();
}
void EQP::CPU::ST::Profiler::Clear() {
for(auto &iter : root_->GetNodes()) {
delete iter.second;
}
root_->GetNodes().clear();
root_->SetTime(0);
root_->SetCount(0);
current_ = root_;
identifier_ = CreateUUID();
}
void EQP::CPU::ST::Profiler::Dump(std::ostream &stream, int num) {
uint64_t total = 0;
std::vector<ProfilerNodeDump> sorted_vec;
sorted_vec.reserve(root_->GetNodes().size() + 1);
for(auto &iter : root_->GetNodes()) {
ProfilerNodeDump n;
n.name = iter.first;
n.node = iter.second;
sorted_vec.push_back(n);
total += iter.second->GetTime();
if(iter.second->GetStarted() > 0) {
total += GetCurrentTimer() - iter.second->GetStarted();
}
}
std::sort(sorted_vec.begin(), sorted_vec.end(),
[](const ProfilerNodeDump& a, const ProfilerNodeDump& b) { return a.node->GetTime() > b.node->GetTime(); });
std::streamsize p = stream.precision();
double m_cycles = total / 1000.0;
stream << std::fixed;
stream.precision(2);
stream << m_cycles << "k cycles" << std::endl;
stream.precision(p);
int i = 0;
for(auto &iter : sorted_vec) {
if(num > 0 && i >= num) {
break;
}
iter.node->Dump(stream, iter.name, total, 1, num);
++i;
}
}
EQP::CPU::MT::Profiler::ThreadInfo::ThreadInfo() {
root_ = new ProfilerNode;
root_->SetParent(root_);
current_ = root_;
}
EQP::CPU::MT::Profiler::ThreadInfo::~ThreadInfo() {
delete root_;
}
EQP::CPU::MT::Profiler::Profiler() {
imp_ = new impl;
imp_->identifier_ = CreateUUID();
}
EQP::CPU::MT::Profiler::~Profiler() {
delete imp_;
}
std::string EQP::CPU::MT::Profiler::EventStarted(const char *func, const char *name) {
std::string cur_name = func;
if(name) {
cur_name += " - ";
cur_name += name;
}
ThreadInfo *ti = nullptr;
std::lock_guard<std::mutex> lg(imp_->lock_);
auto ti_search = imp_->nodes_.find(std::this_thread::get_id());
if(ti_search == imp_->nodes_.end()) {
ti = new ThreadInfo;
imp_->nodes_[std::this_thread::get_id()] = ti;
} else {
ti = ti_search->second;
}
auto search = ti->current_->GetNodes().find(cur_name);
if(search != ti->current_->GetNodes().end()) {
ti->current_ = search->second;
}
else {
ProfilerNode *t = new ProfilerNode;
t->SetParent(ti->current_);
ti->current_->GetNodes()[cur_name] = t;
ti->current_ = t;
}
ti->current_->GetCount()++;
ti->current_->SetStarted(GetCurrentTimer());
return imp_->identifier_;
}
void EQP::CPU::MT::Profiler::EventFinished(uint64_t time, std::string ident) {
ThreadInfo *ti = nullptr;
std::lock_guard<std::mutex> lg(imp_->lock_);
if(ident.compare(imp_->identifier_) != 0) {
return;
}
auto ti_search = imp_->nodes_.find(std::this_thread::get_id());
if(ti_search == imp_->nodes_.end()) {
return;
}
else {
ti = ti_search->second;
}
ti->current_->SetStarted(0);
ti->current_->GetTime() += time;
ti->current_ = ti->current_->GetParent();
}
void EQP::CPU::MT::Profiler::Clear() {
std::lock_guard<std::mutex> lg(imp_->lock_);
for(auto &iter : imp_->nodes_) {
delete iter.second;
}
imp_->nodes_.clear();
imp_->identifier_ = CreateUUID();
}
void EQP::CPU::MT::Profiler::Dump(std::ostream &stream, int num) {
std::lock_guard<std::mutex> lg(imp_->lock_);
for(auto &iter : imp_->nodes_) {
uint64_t total = 0;
std::vector<ProfilerNodeDump> sorted_vec;
sorted_vec.reserve(iter.second->root_->GetNodes().size() + 1);
for(auto &t_iter : iter.second->root_->GetNodes()) {
ProfilerNodeDump n;
n.name = t_iter.first;
n.node = t_iter.second;
sorted_vec.push_back(n);
total += t_iter.second->GetTime();
if(t_iter.second->GetStarted() > 0) {
total += GetCurrentTimer() - t_iter.second->GetStarted();
}
}
std::sort(sorted_vec.begin(), sorted_vec.end(),
[](const ProfilerNodeDump& a, const ProfilerNodeDump& b) { return a.node->GetTime() > b.node->GetTime(); });
std::streamsize p = stream.precision();
double m_cycles = total / 1000.0;
stream << std::fixed;
stream.precision(2);
stream << "Thread: " << iter.first << ", " << m_cycles << "k cycles" << std::endl;
stream.precision(p);
int i = 0;
for(auto &t_iter : sorted_vec) {
if(num > 0 && i >= num) {
break;
}
t_iter.node->Dump(stream, t_iter.name, total, 1, num);
++i;
}
stream << std::endl;
}
}
-112
View File
@@ -1,112 +0,0 @@
#pragma once
#ifdef EQPERF_ENABLED
#include <string>
#include <fstream>
#include <time.h>
#include "eqp_profile_event.h"
#include "eqp_profiler_node.h"
#define eqp_comb_fin(x, y) x##y
#define eqp_comb(x, y) eqp_comb_fin(x, y)
#ifndef EQP_MULTITHREAD
#define _eqp EQP::CPU::ST::Event eqp_comb(eq_perf_event_, __LINE__) (__PRETTY_FUNCTION__);
#define _eqpn(x) EQP::CPU::ST::Event eqp_comb(eq_perf_event_, __LINE__) (__PRETTY_FUNCTION__, x);
#define _eqp_clear() EQP::CPU::ST::GetProfiler().Clear()
#define _eqp_dump(strm, count) EQP::CPU::ST::GetProfiler().Dump(strm, count)
#define _eqp_dump_file(name) char time_str[128]; \
time_t result = time(nullptr); \
strftime(time_str, sizeof(time_str), "%Y_%m_%d_%H_%M_%S", localtime(&result)); \
std::string prof_name = "./profile/"; \
prof_name += name; \
prof_name += "_"; \
prof_name += time_str; \
prof_name += ".log"; \
std::ofstream profile_out(prof_name, std::ofstream::out); \
if(profile_out.good()) { \
_eqp_dump(profile_out, 10); \
}
#else
#define _eqp EQP::CPU::MT::Event eqp_comb(eq_perf_event_, __LINE__) (__PRETTY_FUNCTION__);
#define _eqpn(x) EQP::CPU::MT::Event eqp_comb(eq_perf_event_, __LINE__) (__PRETTY_FUNCTION__, x);
#define _eqp_clear() EQP::CPU::MT::GetProfiler().Clear()
#define _eqp_dump(strm, count) EQP::CPU::MT::GetProfiler().Dump(strm, count)
#define _eqp_dump_file(name) char time_str[128]; \
time_t result = time(nullptr); \
strftime(time_str, sizeof(time_str), "%Y_%m_%d_%H_%M_%S", localtime(&result)); \
std::string prof_name = "./profile/"; \
prof_name += name; \
prof_name += "_"; \
prof_name += time_str; \
prof_name += ".log"; \
std::ofstream profile_out(prof_name, std::ofstream::out); \
if(profile_out.good()) { \
_eqp_dump(profile_out, 10); \
}
#endif
namespace EQP
{
namespace CPU
{
namespace ST
{
class EQP_EXPORT Profiler
{
typedef EQP::CPU::ProfilerNode Node;
public:
Profiler();
~Profiler();
std::string EventStarted(const char *func, const char *name);
void EventFinished(uint64_t time, std::string ident);
void Dump(std::ostream &stream, int num = 0);
void Clear();
private:
Node *root_;
Node *current_;
std::string identifier_;
};
EQP_EXPORT Profiler &GetProfiler();
}
namespace MT
{
class EQP_EXPORT Profiler
{
typedef EQP::CPU::ProfilerNode Node;
class ThreadInfo {
public:
ThreadInfo();
~ThreadInfo();
Node *root_;
Node *current_;
};
public:
Profiler();
~Profiler();
std::string EventStarted(const char *func, const char *name);
void EventFinished(uint64_t time, std::string ident);
void Dump(std::ostream &stream, int num = 0);
void Clear();
private:
struct impl;
impl *imp_;
};
EQP_EXPORT Profiler &GetProfiler();
}
} // CPU
} // EQP
#else
#define _eqp
#define _eqpn(x)
#define _eqp_clear()
#define _eqp_dump(strm, count)
#endif

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