Compare commits

..

207 Commits

Author SHA1 Message Date
Uleat 38572fe393 Merge branch 'master' of https://github.com/EQEmu/Server 2014-09-30 16:18:51 -04:00
Uleat 83367ee806 Added clicky items from bags for clients that support it (RoF, currently) 2014-09-30 16:18:25 -04:00
Michael Cook (mackal) f117aafc45 Added some updownsign to some newer formulas 2014-09-30 13:41:42 -04:00
Alex 3e0c1bc02e Merge pull request #243 from addtheice/RunQueryToDatabaseQuery_zone_npc
Run query to database query zone npc
2014-09-29 17:22:53 -07:00
Alex f13a1d6351 Merge pull request #236 from addtheice/RunQueryToDatabaseQuery_zone_bot
Run query to database query zone bot
2014-09-29 17:20:53 -07:00
Michael Cook (mackal) fdde64dcc3 Merge pull request #255 from noudess/master
Update zone.cpp to fix bug in loading merchantlist_temp
2014-09-29 16:57:35 -04:00
Paul Coene f5fa07c8db Update zone.cpp 2014-09-29 16:38:18 -04:00
Michael Cook (mackal) 5ffb6bdee7 Reworked blind running around
This should be more in line with how we do current fearpath stuff
and with live.
2014-09-29 16:32:48 -04:00
Michael Cook (mackal) 8035c6c558 Correct "cure blindness" catch 2014-09-29 16:16:19 -04:00
Michael Cook (mackal) fc1eca0f31 Merge pull request #254 from noudess/master
Changes so that blind effects like those in Flash of Light work.
2014-09-29 14:26:51 -04:00
Michael Cook (mackal) 28e49801b7 Fix issue with newly inserted saylinks not working correctly
Sadly still silly
2014-09-29 03:08:30 -04:00
Michael Cook (mackal) 66c171b61b Add support for post June 18, 2014 Hundred Hands effects
Set Spells:Jun182014HundredHandsRevamp to true if your spell file is newer
2014-09-28 13:27:38 -04:00
Michael Cook (mackal) 3be7d45d36 Revamp attack delays / hastes / slows based on dev quotes
See changelog
2014-09-27 23:14:11 -04:00
Michael Cook (mackal) e5822a0c4a Fix client SetAttackTimer issue
Moved the call to the end of Client::CalcBonuses() since it depends on
Client::CalcHaste() which requires a bunch of others to be called
before it.
2014-09-27 21:37:14 -04:00
KimLS b05dd45d62 Merge branch 'spell_stats' 2014-09-27 14:45:20 -07:00
KimLS 9f64092606 Merge of kayen's PR as well as some fixes i saw 2014-09-27 14:44:48 -07:00
Paul Coene d2acd0505c is_blind works better as an else to the line that handles cure 2014-09-27 17:39:30 -04:00
Paul Coene 05ed577e23 Fixed issue where blind flag was set for beneficial spells like cure.wq 2014-09-27 17:17:12 -04:00
KayenEQ 7831162235 changelog 2014-09-27 16:39:37 -04:00
KayenEQ 8567fd928a Perl Mob function GetSpellStat(spellid, identifier, slot)
indentifier is the spell_new field
slot is used for effectids,base,base2, max ect where 1 = first slot.
Will add a wiki page
2014-09-27 16:12:10 -04:00
Paul Coene 73a23e9f9d Changes so that blind effects like those in Flash of Light work. 2014-09-27 13:00:07 -04:00
KayenEQ f232bf1ccd Fix for commit failure. 2014-09-27 09:21:37 -04:00
KayenEQ acc6926448 Merge git://github.com/EQEmu/Server into Development 2014-09-27 09:20:27 -04:00
Uleat 837ce8ab4a Re-ordered client patch ENCODES and DECODES - snuck in a bitswap change for SoF+ item_struct::Slots translations 2014-09-26 20:51:42 -04:00
Michael Cook (mackal) 2497c719ee Rename Name variable in SendBazaarResults to temp_buffer fixes #253 2014-09-26 12:43:34 -04:00
KayenEQ 31b46efcac Clean up of perl based NPC spell scaling functions.
Added Perl - $npc->GetSpellFocusDMG(), $npc->GetSpellFocusHeal()
2014-09-26 06:56:42 -04:00
KayenEQ 9f3a0a3f95 Merge git://github.com/EQEmu/Server into Development 2014-09-26 06:54:53 -04:00
Michael Cook (mackal) 179400c777 Client::SetClassStartingSkills should now match live 2014-09-26 00:44:51 -04:00
Michael Cook (mackal) 0f12a74074 Add bool EQEmu::IsSpecializedSkill(SkillUseTypes skill) 2014-09-25 21:40:31 -04:00
Michael Cook (mackal) 61b784e96e Add tests for skills utilities 2014-09-25 21:35:17 -04:00
Michael Cook (mackal) 723e5d536a EQEmu::IsTradeskill uint32 to SkillUseTypes 2014-09-25 21:20:59 -04:00
Alex 225929d937 Merge pull request #240 from addtheice/RunQueryToDatabaseQuery_zone_trading
Run query to database query zone trading
2014-09-25 17:26:48 -07:00
Alex 763ed7f7a3 Merge pull request #242 from addtheice/RunQueryToDatabaseQuery_zone_questmgr
Run query to database query zone questmgr
2014-09-25 17:26:22 -07:00
Alex ea6ef4c283 Merge pull request #245 from addtheice/RunQueryToDatabaseQuery_zone_groups
Run query to database query zone groups
2014-09-25 17:26:13 -07:00
Alex e5a0cc9ef7 Merge pull request #251 from KayenEQ/Development
Fix for calculation for SE_ManaAbsorbPercentDamage
2014-09-25 17:25:45 -07:00
Uleat a79ea9b850 Merge branch 'master' of https://github.com/EQEmu/Server 2014-09-25 18:49:17 -04:00
Uleat 039e321dde More re-enumeration prep work 2014-09-25 18:48:58 -04:00
KimLS c57292a9dd Tired of this GLM warning (and we dont even use glm rotate grr) also reworked how I approached that peq entity process crash after thinking about it a bit 2014-09-25 14:54:40 -07:00
KayenEQ 9561a3fd3e Merge git://github.com/EQEmu/Server into Development 2014-09-25 15:15:32 -04:00
KimLS aa021addc1 Fix for potion belt name loading. 2014-09-25 04:00:06 -07:00
Michael Cook (mackal) c0cbbf3a65 World needs to load skill cap data for char creation 2014-09-25 03:14:43 -04:00
Michael Cook (mackal) a73ac9cfe8 Added helper function bool EQEmu::IsTradeskill(uint32 skill)
Returns true if you pass a tradeskill to it, otherwise false
2014-09-24 23:36:27 -04:00
KimLS ec8c46abfe I keep seeing a crash due to an invalidated iter during mob delete every few days, seeing if this fixes it. 2014-09-24 19:47:27 -07:00
KayenEQ b9b92762b5 Merge git://github.com/EQEmu/Server into Development
Conflicts:
	changelog.txt
2014-09-24 20:51:20 -04:00
Uleat 7feb531ff7 Re-ordered server opcodes and handlers to facilitate the export of client patch structs and handlers 2014-09-24 20:23:01 -04:00
Michael Cook (mackal) e67423bba7 Add raid mob message
"This creature would take an army to defeat!"
Colors may be a bit off due to differences in clients
2014-09-24 14:04:17 -04:00
Michael Cook (mackal) 531e4b0207 Fix function signature of Mob::IsRaidTarget() so its actually a virtual 2014-09-24 13:50:18 -04:00
Michael Cook (mackal) 34496c49b4 Add Client::SendColoredText(uint32 color, std::string message)
This will send a message (arbitrary size limit of 512) to the client
of the provided color. The MT colors should work here.
2014-09-24 13:14:20 -04:00
Michael Cook (mackal) a445d7e39f Rename OP_BuffFadeMsg to OP_ColoredText since it is a generic opcode 2014-09-24 12:22:06 -04:00
KimLS 0d12715d77 Data verification utils, not in use yet. Also added ability for lua packet to bypass the translation layer (dangerous) if a writer so desires (useful for quickly trying packet stuff) 2014-09-24 03:58:46 -07:00
akkadius 9878459049 Fix tribute loading/saving for real 2014-09-23 20:16:19 -05:00
akkadius 9be0d3b090 memset size fix to calc current size of 400 bytes for discipline initialization 2014-09-23 19:19:40 -05:00
akkadius 16ba3eb11e Restoring Disciplines to their original load order (Slot)
Tribute uninitialized value database conversion fix
Tribute load fix (Lost in translation)
Changed Tribute 0 value to 0xFFFFFFFF instead of 0
Sanity check for unitialized tribute value on load
2014-09-23 19:12:31 -05:00
akkadius 973aa94cb5 Fix for database schema conversion where character_ table has 0 characters present. This will allow the tables to still be created properly and the old one renamed. 2014-09-23 18:28:17 -05:00
KimLS 4cbccfdce2 Fix for MoveCharacterToZone using zoneid instead of zone_id 2014-09-23 16:02:04 -07:00
KayenEQ a5e6fa3479 Merge git://github.com/EQEmu/Server into Development 2014-09-23 18:58:59 -04:00
akkadius 3712d36867 Fix for the undye command to properly purge character armor dye 2014-09-23 17:54:07 -05:00
KimLS 17291e9977 Merge branch 'master' of github.com:EQEmu/Server 2014-09-23 15:42:48 -07:00
KimLS 15f57e4a4c Rob's broken skill up bug reported fixed 2014-09-23 15:42:20 -07:00
akkadius e58d63bf35 IncrementAA for scripting functions changed to use SaveAA instead of Save 2014-09-23 17:21:08 -05:00
KimLS f89add9f64 Fix for AA conversion 2014-09-23 15:09:33 -07:00
Michael Cook (mackal) e039f6d2c6 Fix AA issue 2014-09-23 17:40:17 -04:00
KimLS 7cef4d8fe9 Fix for spell books on newer clients not playing well with the tricksy new deblob code 2014-09-23 13:39:05 -07:00
KimLS 7b85b09f24 isnan fix for vs2012 2014-09-23 13:04:18 -07:00
akkadius 413538f1b5 Sending the client a spell value that is more inline with what it expects when no spell is set. 2014-09-23 14:40:09 -05:00
KayenEQ c03a70651c SE_ApplySpell and SE_TriggerSpell will now be applied based on which effect slot they are used in (instead of always before all spell effects are checked).
Note: If a spell has multiple SE_TriggerSpell effects within it. Only one will be able to trigger. (If you want multiple spells use SE_ApplySpell)
2014-09-23 09:15:02 -04:00
KayenEQ ec01e6c69b Merge git://github.com/EQEmu/Server into Development 2014-09-23 09:07:14 -04:00
KimLS 11773208df Style cleanup, clamp hunger and thirst values to correct ranges 2014-09-22 16:46:01 -07:00
KayenEQ 1f155690d8 Fix to SE_ApplyEffect - Will now trigger spell from this effect at correct time. 2014-09-22 19:42:59 -04:00
KimLS 36a29dbb9f Fix for creating characters failing at name verification 2014-09-22 15:37:11 -07:00
KayenEQ c160b8716f Kayen: Spell recourse effects / triggerable spell effects will now be applied AFTER the base spells effects have been applied (consistent with live). 2014-09-22 18:02:40 -04:00
KayenEQ 7ffce01260 Merge git://github.com/EQEmu/Server into Development 2014-09-22 17:50:35 -04:00
akkadius 1170b57fd5 Fix starting items for starting_item entries that use slot -1 to find a free slot 2014-09-22 16:23:43 -05:00
akkadius fee8a1214a Putting back in demonstar's lowercase check 2014-09-22 02:52:23 -05:00
akkadius c26a6959e4 #resetaa now covers the function of #resetaa and #refundaa
#resetaa will wipe all AA data, refund the spent points into the available points and send character to character select properly
Removed #refundaa
Removed a lot of debug code for blob conversion
Changed status logging for loads/saves to Debug category
2014-09-22 01:00:28 -05:00
akkadius 837b9b7ec7 NoRentExpired character_ reference 2014-09-21 23:54:52 -05:00
akkadius a5a8bfb0f4 Bye bye commented old junk 2014-09-21 23:48:51 -05:00
akkadius 69bddef5a0 Merge branch 'master' of https://github.com/EQEmu/Server 2014-09-21 23:35:27 -05:00
akkadius 7d242045ec Another merge aftermath overwriting character_data reference to old table 2014-09-21 23:34:53 -05:00
JJ c3035fdf41 Merge branch 'master' of https://github.com/EQEmu/Server 2014-09-21 20:03:09 -04:00
JJ e34c47414f Consistent directory locations under common. 2014-09-21 20:02:01 -04:00
akkadius 909dda7c09 Array iter fix 2014-09-21 19:01:50 -05:00
KimLS 22ab145f19 Merge branch 'master' of github.com:EQEmu/Server 2014-09-21 15:59:24 -07:00
KimLS cd8e30a2ec Bug with MySQLRequestResult 2014-09-21 15:59:02 -07:00
akkadius 03be6b2b6b Debug message adjustments 2014-09-21 16:24:06 -05:00
akkadius cda2217634 .......................................... 2014-09-21 04:26:26 -05:00
KimLS 4525b512ac Build fix plus future travis update 2014-09-21 02:25:05 -07:00
akkadius db0d1116f8 make travis shut up 2014-09-21 04:12:36 -05:00
akkadius 3ef5d8ef0a gcc fix <stdint.h> vs <limits> 2014-09-21 03:43:27 -05:00
akkadius 4ed88e348e Merge aftermath 2014-09-21 02:58:56 -05:00
akkadius ad29fa9cfa Merge remote-tracking branch 'remotes/origin/master' into blob_conversion
Conflicts:
	changelog.txt
	common/database.cpp
	world/client.cpp
	world/zoneserver.cpp
	zone/command.cpp
2014-09-21 02:32:31 -05:00
akkadius 388c4bc574 Fix where if players instance is expired when logging back into it, they will get sent properly to bind. Issue was players player profile instance ID did not match the bind instance ID. 2014-09-21 02:27:57 -05:00
KimLS b4f3993616 Should compile on gcc now 2014-09-20 23:56:04 -07:00
akkadius f9366553a3 Blob changelog.txt 2014-09-21 01:27:05 -05:00
KimLS 9733f04c9c Merge of changelog, how i hate thee 2014-09-20 15:10:33 -07:00
KimLS 7140a2054f Ban and suspend commands now require a reason that is recorded in the DB 2014-09-20 15:09:43 -07:00
Michael Cook (mackal) 1049e48aca Add Spells:SHDProcIDOffByeOne to support newer spell files
In June 2009 SoE stopped doing a +1 to the base for SHD procs
So UF+ spell files were not working, set this to false to support these spell files
2014-09-20 16:58:35 -04:00
Michael Cook (mackal) 33b79a3588 Limit character length to 15 (the client doesn't let you enter more) 2014-09-20 15:59:34 -04:00
Michael Cook (mackal) f82699c39b Fix crash in SendEnterWorld on illegally long names 2014-09-20 15:55:20 -04:00
Michael Cook (mackal) 15eaf4e6d1 Fix issue with not online message from tells 2014-09-20 14:57:15 -04:00
Michael Cook (mackal) 7621882b4e Fix toon names being allowed with lower case starting char 2014-09-20 02:46:04 -04:00
akkadius 52608d9b2d Character armor dye save fix 2014-09-18 22:46:28 -05:00
akkadius 3cb02e3b86 Merge branch 'blob_conversion' of https://github.com/EQEmu/Server into blob_conversion 2014-09-17 20:19:04 -05:00
akkadius 34c3b8628e Merge from master 2014-09-17 20:16:37 -05:00
KimLS 8f921ce919 Merge branch 'blob_conversion' of github.com:EQEmu/Server into blob_conversion 2014-09-17 17:45:53 -07:00
KimLS 6754dfdf6d Small sanity checks that was causing a few errors 2014-09-17 17:45:40 -07:00
akkadius 81722962cf KLS Nazi Grammar Fix 2014-09-17 14:30:19 -05:00
KayenEQ d169d95ab0 Fix for resource tap when gaining/loosing HP. 2014-09-17 12:08:01 -04:00
KayenEQ 63ca4cac5e Fix for calculation for SE_ManaAbsorbPercentDamage 2014-09-17 05:14:10 -04:00
akkadius f30ae9dd5a Some descriptor adjustments 2014-09-17 02:52:13 -05:00
akkadius eb49707779 Changed conversion routine.
At the end of conversion, character_ table will be renamed to character_old so that it does not get hit with trying to convert next world bootup
Added some file logging during the initial conversion routine
2014-09-17 02:47:13 -05:00
akkadius 87bb5deb5c Added quest::crosszonesetentityvariablebynpctypeid(npctype_id, id, m_var)
Added quest::crosszonesignalnpcbynpctypeid(npctype_id, data)
Added $client->GetTaskActivityDoneCount(THIS, TaskID, ActivityID)
2014-09-16 16:03:27 -05:00
Akkadius e390531dcd Initial character creation escape sequences
Added initial skill/language/bind saves to character creation
2014-09-11 03:14:34 -05:00
akkadius d7dc733480 Small db changes 2014-09-11 00:44:12 -05:00
akkadius 0c38b46bf1 Remove namespace std 2014-09-09 16:15:25 -05:00
akkadius 899cf32e6b Added some DB logging to catch any potential query errors, this logs to eqemu_query_error_log.txt at the root folder, currently no rule toggling for this
Corrected some character name reservation logic
Adjusted telnet console so it does not throw 'Command Unknown' when simply hitting enter key
Adjusted System MSG for worldshutdown to use minutes instead of seconds
Added warning for when Shared platinum is disabled at the rule level for players to NOT put platinum in the shared bank when they insert platinum in the shared platinum slot
Changed a place in the code where disciplines were trained, someone had uint16 allocated to CharacterID and this was causing issues for characters with large ID's in the database
Added a fix for bind points getting overwritten with invalid zone data, setting everything to 0,0,0,0 - Since I've added this change I've had no issues for players
Fixed some spell book swap logic in the code, removed swap function.
Fixed issue with guild ranks not loading properly
Commented out some of the non-working tell-que code
Took out some of the auto increment settings in the auto database conversion that don't affect anything anyways
Added some additional escape string sequences for queries that needed them
Added ThrowDBError logging to catch any potential query issues with saves or load functions
2014-09-09 16:03:24 -05:00
akkadius 1f9597a9e2 Fix for item dupe via RoF augmenting 2014-09-07 05:35:19 -05:00
akkadius 54c89d69f6 Merge remote-tracking branch 'remotes/origin/master' into blob_conversion
Conflicts:
	common/database.cpp
	common/mysql_request_result.h
	common/shareddb.cpp
2014-09-07 04:11:09 -05:00
akkadius a14371ba5c Removed debugging
Added player profile data loading safety net checking
2014-09-07 04:00:56 -05:00
Akkadius 4c12d31e4a Removed command character backup
Changed all remaining references from the character_ table to the character_data
2014-09-06 22:35:19 -05:00
Akkadius e50cf5c4be - Ported inspect_messages to character_inspect_messages
- Ported character leadership abilities to character_leadership_abilities
- Removed player profile debug printing
- Refactored total time entitled on account to load from the sum of time_played from all characters in character_data
2014-09-06 21:50:29 -05:00
akkadius ca7dd7d741 - Improved speed of character database conversion x1000 by changing query style
- Adjusted AA MySQL saves for 100x speed increase
- Removed StoreCharacter lookup methods as they will no longer be necessary
- Some other cleanup
2014-09-06 13:53:54 -05:00
Arthur Ice 59618e0038 UnDelegateMarkNPC converted to QueryDatabase 2014-09-05 16:14:28 -07:00
Arthur Ice ef1f1562f0 DelegateMarkNPC converted to QueryDatabase 2014-09-05 16:13:50 -07:00
Arthur Ice 31177b7dc7 UnDelegatePuller converted to QueryDatabase 2014-09-05 16:04:34 -07:00
Arthur Ice 5b7aaff150 UnDelegateMainAssist converted to QueryDatabase 2014-09-05 15:58:21 -07:00
Arthur Ice b525a32b6e UndelegateMainTank converted to QueryDatabase 2014-09-05 15:54:07 -07:00
Arthur Ice 99fe610f72 DelegatePuller converted to QueryDatabase 2014-09-05 15:46:06 -07:00
Arthur Ice b5ec35e672 DelegateMainTank converted to QueryDatabase 2014-09-05 15:27:12 -07:00
Arthur Ice 15fa2b371c LearnMembers converted to QueryDatabase 2014-09-05 10:45:36 -07:00
Arthur Ice 0799b47c9c AddSpawnFromSpawnGroup converted to QueryDatabase 2014-09-04 19:40:19 -07:00
Arthur Ice a216672443 Moved add spawn from spawn group command case (5) from NPCSpawnDB into method AddSpawnFromSpawnGroup 2014-09-04 18:13:23 -07:00
Arthur Ice d755aa48bc DeleteSpawnRemoveFromNPCTypeTable converted to QueryDatabase 2014-09-04 17:15:09 -07:00
Arthur Ice f7ecfe7257 DeleteSpawnLeaveInNPCType converted to QueryDatabase 2014-09-04 17:01:34 -07:00
Arthur Ice 89a0bbb8bf Moved deleting npc spawn command case (3) from NPCSpawnDB into method DeleteSpawnLeaveInNPCTypeTable 2014-09-04 16:35:01 -07:00
Arthur Ice 822c8425bd UpdateNPCTypeAppearance converted to QueryDatabase 2014-09-04 16:13:43 -07:00
Arthur Ice a6b57a3423 Moved updating npc type appearance command case (2) from NPCSpawnDB into method UpdateNPCTypeAppearance 2014-09-04 15:32:41 -07:00
Arthur Ice 6d4f7413a5 AddNewNPCSpawnGroupCommand converted to QueryDatabase 2014-09-04 15:01:42 -07:00
Arthur Ice 3e041052ee Moved add new NPC spawngroup command case (1) from NPCSpawnDB into method AddNewNPCSpawnGroupCommand 2014-09-04 14:47:02 -07:00
Arthur Ice 444174ef57 CreateNewNPCCommand converted to QueryDatabase 2014-09-04 12:26:05 -07:00
Arthur Ice 970f7e01a9 Moved create new NPC command case (0) from NPCSpawnDB into method CreateNewNPCCommand 2014-09-04 10:08:02 -07:00
Akkadius 4432c07081 State of Commit: Testable if you ask me (Akkadius) what you need to do
- Need to convert a list of functions and columns and should be ready to start intensive testing phase
 - All preliminary tests show things working great

- All of player profile is saved and loaded from the database
- DBAsync has been completely removed from all code
	- Removed zone/dbasync.cpp/.h
	- Removed common/dbasync.cpp/.h
	- Removed dbasync from cmake commmon and zone
- Cleaned up a ton of functions
- Added several tables to world CheckDatabaseConversions script:
	- `character_skills`
	- `character_languages`
	- `character_bind`
	- `character_alternate_abilities`
	- `character_currency`
	- `character_data`
	- `character_spells`
	- `character_memmed_spells`
	- `character_disciplines`
	- `character_material`
	- `character_tribute`
	- `character_bandolier`
	- `character_potionbelt`
- Character select now loads from `character_data`
- Character creation now creates to `character_data`
- Updated function Database::UpdateName to use `character_data`
- Updated function Database::CheckUsedName to use `character_data`
- Updated function Database::MoveCharacterToZone to use `character_data`
- Updated function Database::SetLoginFlags to use `character_data`
- Updated function Database::SetFirstLogon to use `character_data`
- Updated function Database::SetLFG to use `character_data`
- Removed CopyCharacter functions and commands, to be recreated later since it never worked to begin with
- Removed SharedDatabase::SetPlayerProfile
- Trimmed down redundant case switch statements for World sendpackets to QueryServ
- Added Character Methods to Database class:
	Loads:
		bool	LoadCharacterBandolier(uint32 character_id, PlayerProfile_Struct* pp);
		bool	LoadCharacterTribute(uint32 character_id, PlayerProfile_Struct* pp);
		bool	LoadCharacterPotions(uint32 character_id, PlayerProfile_Struct* pp);
	Saves:
		bool	SaveCharacterBindPoint(uint32 character_id, uint32 zone_id, uint32 instance_id, float x, float y, float z, float heading, uint8 is_home);
		bool	SaveCharacterCurrency(uint32 character_id, PlayerProfile_Struct* pp);
		bool	SaveCharacterData(uint32 character_id, uint32 account_id, PlayerProfile_Struct* pp);
		bool	SaveCharacterAA(uint32 character_id, uint32 aa_id, uint32 current_level);
		bool	SaveCharacterSpellSwap(uint32 character_id, uint32 spell_id, uint32 from_slot, uint32 to_slot);
		bool	SaveCharacterSpell(uint32 character_id, uint32 spell_id, uint32 slot_id);
		bool	SaveCharacterMemorizedSpell(uint32 character_id, uint32 spell_id, uint32 slot_id);
		bool	SaveCharacterMaterialColor(uint32 character_id, uint32 slot_id, uint32 color);
		bool	SaveCharacterSkill(uint32 character_id, uint32 skill_id, uint32 value);
		bool	SaveCharacterLanguage(uint32 character_id, uint32 lang_id, uint32 value);
		bool	SaveCharacterDisc(uint32 character_id, uint32 slot_id, uint32 disc_id);
		bool	SaveCharacterTribute(uint32 character_id, PlayerProfile_Struct* pp);
		bool	SaveCharacterBandolier(uint32 character_id, uint8 bandolier_id, uint8 bandolier_slot, uint32 item_id, uint32 icon, const char* bandolier_name);
		bool	SaveCharacterPotionBelt(uint32 character_id, uint8 potion_id, uint32 item_id, uint32 icon);
	Deletes:
		bool	DeleteCharacterSpell(uint32 character_id, uint32 spell_id, uint32 slot_id);
		bool	DeleteCharacterMemorizedSpell(uint32 character_id, uint32 spell_id, uint32 slot_id);
		bool	DeleteCharacterDisc(uint32 character_id, uint32 slot_id);
		bool	DeleteCharacterBandolier(uint32 character_id, uint32 band_id);
2014-09-04 07:24:17 -05:00
Arthur Ice 221c667a23 saylink converted to QueryDatabase 2014-09-03 23:26:09 -07:00
Arthur Ice b710c41c34 clearspawntimers converted to QueryDatabase 2014-09-03 23:17:20 -07:00
Arthur Ice 8825218361 showgrid converted to QueryDatabase 2014-09-03 23:14:16 -07:00
Arthur Ice 1bb5c4e0d8 delglobal converted to QueryDatabase 2014-09-03 23:10:42 -07:00
Arthur Ice 58343480ff InsertQuestGlobal converted to QueryDatabase 2014-09-03 23:07:28 -07:00
Arthur Ice 081905dbc3 SendBuyerResults converted to QueryDatabase 2014-09-03 20:34:07 -07:00
Arthur Ice a8b8f71092 ShowBuyLines converted to QueryDatabase 2014-09-03 20:24:30 -07:00
Arthur Ice 36c1d88eac SendBazaarResults converted to QueryDatabase 2014-09-03 20:18:07 -07:00
Arthur Ice 6eba672013 SendBazaarWelcome converted to QueryDatabase 2014-09-03 19:39:50 -07:00
Arthur Ice 091c8ea5f1 BazaarAuditTrail converted to QueryDatabase 2014-09-03 19:33:20 -07:00
Arthur Ice 95dc0c5fc8 GetEquipmentColor converted to QueryDatabase 2014-09-03 18:49:47 -07:00
Arthur Ice 73c8d3d09d ProcessBoyCommands converted to QueryDatabase 2014-09-03 18:46:41 -07:00
Arthur Ice 049a0bf787 LoadGuildMembership converted to QueryDatabase 2014-09-03 18:41:21 -07:00
Arthur Ice 2095380ba4 SetBotGuildMembership converted to QueryDatabase 2014-09-03 18:31:26 -07:00
Arthur Ice 081192d29e GetBotOwnerCharacterID converted to QueryDatabase 2014-09-03 18:24:30 -07:00
Arthur Ice 2429980fd5 CreatedBotCount converted to QueryDatabase 2014-09-03 18:21:17 -07:00
Arthur Ice 0ac238d762 AllowedBotSpawns converted to QueryDatabase 2014-09-03 18:16:22 -07:00
Arthur Ice 45320fd8ec GetBotGroupLeaderIdByBotGroupName converted to QueryDatabase 2014-09-03 18:13:15 -07:00
Arthur Ice 6d33a13e23 GetBotGroupIdByBotGroupName converted to QueryDatabase 2014-09-03 18:09:53 -07:00
Arthur Ice 52d64d03a6 CanLoadBotGroup converted to QueryDatabase 2014-09-03 18:06:05 -07:00
Arthur Ice fe6e289606 DoesBotGroupNameExist converted to QueryDatabase 2014-09-03 18:01:32 -07:00
Arthur Ice 26569ac51d GetBotGroupListByBotOwnerCharacterId converted to QueryDatabase 2014-09-03 17:57:10 -07:00
Arthur Ice 38d04931ba LoadBotGroup converted to QueryDatabase 2014-09-03 17:52:06 -07:00
Arthur Ice 96cf3d967f DeleteBotGroup converted to QueryDatabase 2014-09-03 17:47:38 -07:00
Arthur Ice 36325226eb SaveBotGroup converted to QueryDatabase 2014-09-03 17:43:18 -07:00
Arthur Ice 6410f52c9c ListSpawnedBots converted to QueryDatabase 2014-09-03 17:36:59 -07:00
Arthur Ice 7ae14fffd0 GetBotList converted to QueryDatabase 2014-09-03 17:32:55 -07:00
Arthur Ice d213e3b106 GetGroupedBotsByGroupID converted to QueryDatabase 2014-09-03 17:26:51 -07:00
Arthur Ice ba612f91c7 LoadBot converted to QueryDatabase 2014-09-03 17:18:50 -07:00
Arthur Ice 8312a8cf3b GetBotIDByBotName converted to QueryDatabase 2014-09-03 17:11:06 -07:00
Arthur Ice 390dcc9a88 GetBotItemsCount converted to QueryDatabase 2014-09-03 17:07:11 -07:00
Arthur Ice cd1b45f0d6 GetBotItemBySlot converted to QueryDatabase 2014-09-03 17:04:21 -07:00
Arthur Ice b8caa5dc31 GetBotItems converted to QueryDatabase 2014-09-03 16:52:18 -07:00
Arthur Ice 53572b4d13 RemoveBotItemBySlot converted to QueryDatabase 2014-09-03 16:43:59 -07:00
Arthur Ice cf0c773002 SetBotItemInSlot converted to QueryDatabase 2014-09-03 16:40:31 -07:00
Arthur Ice 515fe8d9e5 DeleteBot converted to QueryDatabase 2014-09-03 16:31:08 -07:00
Arthur Ice 06d1bd632b SaveTimers converted to QueryDatabase 2014-09-03 16:31:08 -07:00
Arthur Ice 89f34246f0 LoadTimers converted to QueryDatabase 2014-09-03 16:31:08 -07:00
Arthur Ice 7d8e128b5f SaveStance converted to QueryDatabase 2014-09-03 16:31:08 -07:00
Arthur Ice 14c642a3f7 LoadStance converted to QueryDatabase 2014-09-03 16:31:07 -07:00
Arthur Ice a67255475c DeletePetStats converted to QueryDatabase 2014-09-03 16:31:07 -07:00
Arthur Ice 04045dfc27 DeletePetItems converted to QueryDatabase 2014-09-03 16:31:07 -07:00
Arthur Ice 510a51e564 DeletePetBuffs converted to QueryDatabase 2014-09-03 16:31:07 -07:00
Arthur Ice 54b2c50109 SavePetItems converted to QueryDatabase 2014-09-03 16:31:07 -07:00
Arthur Ice fe753f05df SavePetBuffs converted to QueryDatabase 2014-09-03 16:31:07 -07:00
Arthur Ice ab76783f8b SavePetStats converted to QueryDatabase 2014-09-03 16:31:07 -07:00
Arthur Ice 364a51b119 LoadPetItems converted to QueryDatabase 2014-09-03 16:31:07 -07:00
Arthur Ice a486db5e95 LoadPetBuffs converted to QueryDatabase 2014-09-03 16:31:06 -07:00
Arthur Ice c8e7d9e005 LoadPetStats converted to QueryDatabase 2014-09-03 16:31:06 -07:00
Arthur Ice 93aa690a6d GetPetSaveId converted to QueryDatabase 2014-09-03 16:31:06 -07:00
Arthur Ice 87f1f78b67 LoadBuffs converted to QueryDatabase 2014-09-03 16:31:06 -07:00
Arthur Ice 0574a3db86 SaveBuffs converted to QueryDatabase 2014-09-03 16:31:06 -07:00
Arthur Ice 0178f3c9bb Save converted to QueryDatabase 2014-09-03 16:31:06 -07:00
Arthur Ice 9eb3907d45 IsBotNameValid converted to QueryDatabase 2014-09-03 16:31:06 -07:00
Arthur Ice 118c2a9db9 LoadAAs converted to QueryDatabase 2014-09-03 13:49:04 -07:00
Akkadius 0a9222e1ee - 2014-09-01 23:54:15 -05:00
Akkadius e0db3c0b60 Fixed Character select to be loaded from new character data tables 2014-09-01 22:17:06 -05:00
Akkadius e0a99730e5 pp revert 2014-08-31 21:58:04 -05:00
Akkadius 6497bdf45a More stuff 2014-08-31 21:31:44 -05:00
Akkadius ca430e2494 Fix void Database::GetCharName(uint32 char_id, char* name)
Increased MAX_PP_SPELLBOOK to 720 for UF/RoF
Increased MAX_PP_MEMSPELL to 12
Implemented up to 12 spell slots
Fix for public_note default value in bool BaseGuildManager::DBSetGuild(uint32 charid, uint32 guild_id, uint8 rank)
Updated all CastSpell entries to use the appropriate slot type defines located now in zone/common.h
Fixed Guild Loading from character_data
Fixed #guild list
Refactored Merchantlist loading
Refactored Temp Merchantlist loading
Gutted most of dbasync

Added:
LoadCharacterSpellBook(uint32 character_id, PlayerProfile_Struct* pp);
LoadCharacterMemmedSpells(uint32 character_id, PlayerProfile_Struct* pp);
LoadCharacterLanguages(uint32 character_id, PlayerProfile_Struct* pp);
LoadCharacterBindPoint(uint32 character_id, PlayerProfile_Struct* pp);
SaveCharacterSpellSwap(uint32 character_id, uint32 spell_id, uint32 from_slot, uint32 to_slot);
SaveCharacterSpell(uint32 character_id, uint32 spell_id, uint32 slot_id);
SaveCharacterMemorizedSpell(uint32 character_id, uint32 spell_id, uint32 slot_id);
DeleteCharacterSpell(uint32 character_id, uint32 spell_id, uint32 slot_id);
DeleteCharacterMemorizedSpell(uint32 character_id, uint32 spell_id, uint32 slot_id);

Removed Zone::LoadTempMerchantData_result(MYSQL_RES* result)
Removed Zone::LoadMerchantData_result(MYSQL_RES* result)
Removed SharedDatabase::GetPlayerProfile
Removed SharedDatabase::SetPlayerProfile
Removed SharedDatabase::SetPlayerProfile_MQ
Removed Zone::DBAWComplete(uint8 workpt_b1, DBAsyncWork* dbaw) from zone.cpp
2014-08-31 17:52:43 -05:00
Akkadius f8439fd6e6 Made many adjustments to character load code.
Removed bool Client::FinishConnState2(DBAsyncWork* dbaw)
Removed all async character loads
Removed bool	GetAccountInfoForLogin
Removed bool	GetAccountInfoForLogin_result
Removed bool	GetCharacterInfoForLogin_result
Removed bool	GetCharacterInfoForLogin

Added:
bool	LoadCharacterFactionValues(uint32 character_id, faction_map & val_list);
bool	LoadCharacterDisciplines(uint32 character_id, PlayerProfile_Struct* pp);
bool	LoadCharacterSkills(uint32 character_id, PlayerProfile_Struct* pp);
2014-08-31 07:52:52 -05:00
Akkadius 8dda7ddd04 Added the following tables to player profile automatic conversion during world bootup:
`character_bind_home`;
`character_alternate_abilities`;
`character_currency`;
`character_data`;
`character_spells`;
`character_memmed_spells`;
`character_disciplines`;
2014-08-31 05:52:36 -05:00
Akkadius 5d8ea5752d Added automatic table creation in conversion process.
More will come when more tables are added
2014-08-31 03:23:42 -05:00
akkadius 4071d88290 At point of commit:
Basic character data, currency and AA are being loaded/saved from the database, currently working on the rest right now.
- Character blob removed from load for testing. Lots of cleanup yet to be done so don't judge code yet.

Saves:
- Two FULL saves when looting a corpse, this has been reduced to just currency saves on initial loot and trimmed to one save since AddToMoneyPP did it already
- Every time a player moves coin with any situation (Splits/Trades/Merchant/Skills/Bank Coin Exchange/Coin Moves), a full save is made, this is now just a currency save
- Every time a player skilled up at a skill vendor, a full blob save hit was made, this is not just a currency hit
2014-08-31 02:53:59 -05:00
Akkadius 5cf748d135 Initial work 2014-08-27 09:55:39 -05:00
141 changed files with 36692 additions and 35835 deletions
+3 -1
View File
@@ -8,7 +8,9 @@ script:
- make
- ./bin/tests
branches:
only: master
only:
- master
- stable
notifications:
email: false
irc:
+1
View File
@@ -289,6 +289,7 @@ ADD_DEFINITIONS(-DLOG_LEVEL_DEBUG=${EQEMU_LOG_LEVEL_DEBUG})
ADD_DEFINITIONS(-DLOG_LEVEL_QUEST=${EQEMU_LOG_LEVEL_QUEST})
ADD_DEFINITIONS(-DLOG_LEVEL_COMMANDS=${EQEMU_LOG_LEVEL_COMMANDS})
ADD_DEFINITIONS(-DLOG_LEVEL_CRASH=${EQEMU_LOG_LEVEL_CRASH})
ADD_DEFINITIONS(-DGLM_FORCE_RADIANS)
IF(EQEMU_STREAM_RETRANSMIT_ACKED_PACKETS)
ADD_DEFINITIONS(-DRETRANSMIT_ACKED_PACKETS=true)
+136
View File
@@ -1,8 +1,144 @@
EQEMu Changelog (Started on Sept 24, 2003 15:50)
-------------------------------------------------------
== 09/30/2014 ==
Uleat: Implemented click-casting from bag slots for clients that natively support it (RoF)
== 09/28/2014 ==
demonstar55: Add support for post June 18, 2014 Hundred Hands Effect spells (they changed the formula and stuff)
set Spells:Jun182014HundredHandsRevamp to true if you're using a spell file from June 18, 2014+
== 09/27/2014 ==
Kayen: Implemented perl function $mob->GetSpellStat(spell_id, identifier, slot);
Note: identifier is the stat field in spells_new, slot is used for certain effects like effectid, base,base2, max ect.
Example $mob->GetSpellStat(121, "range"); //Returns spell range
Example $mob->GetSpellStat(121, "effectid", 1); //Returns the the value of effectid1
This will allow you to pull almost all the data for any spell in quest files.
demonstar55: Move the client's SetAttackTimer to the end of Client::CalcBonuses to keep the haste in sync
demonstar55: Correct haste/slow "stacking" rules
demonstar55: Correct SE_AttackSpeed4 to respect unslowable
demonstar55: Make the haste be between 1-225 like the client (<100 = slow, >100 = haste) to ...
demonstar55: Correct Hundred Hands effect and use formula provided by devs
== 09/24/2014 ==
Uleat: Re-ordered server opcodes and handlers to give them some predictability of location (I need this for the inventory re-enumeration.)
demonstar55: Added helper function bool EQEmu::IsTradeskill(uint32 skill)
== 09/23/2014 ==
Kayen: Spell recourse effects will now be applied AFTER the base spells effects have been applied (consistent with live).
Kayen: SE_ApplySpell and SE_TriggerSpell will now be applied based on which effect slot they are used in (instead of always before all spell effects are checked).
Note: If a spell has multiple SE_TriggerSpell effects within it. Only one will be able to trigger. (If you want multiple spells use SE_ApplySpell)
== 09/22/2014 ==
Akkadius: #resetaa now covers the function of #resetaa and #refundaa
- #resetaa will wipe all AA data, refund the spent points into the available points and send character to character select properly
Akkadius: Removed #refundaa
Akkadius: Removed a lot of debug code for blob conversion
Akkadius: Changed status logging for loads/saves to Debug category
== 09/21/2014 ==
Akkadius: Player Profile Blob to Database Conversion
- Summary: HUGE difference in database speeds reads/writes and 1:10 datasize difference
- The new character storage engine unlike the character_ table before, is able to properly index data and make use of
proper MySQL/MariaDB caching optimizations and performance has increased phenominally
PERFORMANCE AND STATISTICS FIGURES (Varies on hardware):
- EZ Server Character data size of 2.6GB `character_` table alone now takes up approx 600MB
- Character Data Loads take approx .03 seconds BEFORE MySQL/MariaDB cache
- Character Data Loads take approx .001-.0035 seconds AFTER MySQL/MariaDB cache
- Character Data Saves take approx .0001 - .003 for any particular save operation
- Database Auto Conversion: When the 'character_' table exists, World boot-up will queue an auto-conversion prompt and convert all of your characters, BACKUP
YOUR DATABASE BEFORE CONVERTING, here is an EASY backup script: http://wiki.eqemulator.org/p?MySQL_DB_Backup_Script
- On auto conversion, the following tables are created automatically:
- Table: `character_skills` - Stores Character Skills
- Table: `character_languages` - Stores Character Language
- Table: `character_bind` - Stores Character Bind point and Home Bind point designated by is_home bool field
- Table: `character_alternate_abilities` - Stores all Character AA
- Table: `character_currency` - Stores all Platinum/Gold/Silver/Copper and character related currencies
- Table: `character_data` - Stores basic character data (Fields from `character_` table migrated to this table)
- Table: `character_spells` - Stores character spells
- Table: `character_memmed_spells` - Stores character memorized spells
- Table: `character_disciplines` - Stores character disciplines
- Table: `character_material` - Stores character armor dye textures
- Table: `character_tribute` - Stores character tributes
- Table: `character_bandolier` - Stores character bandoliers
- Table: `character_inspect_messages` - Stores character inspection messages (Moved from `character_` table)
- Table: `character_leadership_abilities` - Stores character Leadership AAs
- Loads: Majority of Player profile loads now occur at Client::Handle_Connect_OP_ZoneEntry
LoadCharacterFactionValues(uint32 character_id, faction_map & val_list);
LoadCharacterSpellBook(uint32 character_id, PlayerProfile_Struct* pp);
LoadCharacterMemmedSpells(uint32 character_id, PlayerProfile_Struct* pp);
LoadCharacterLanguages(uint32 character_id, PlayerProfile_Struct* pp);
LoadCharacterDisciplines(uint32 character_id, PlayerProfile_Struct* pp);
LoadCharacterSkills(uint32 character_id, PlayerProfile_Struct* pp);
LoadCharacterData(uint32 character_id, PlayerProfile_Struct* pp, ExtendedProfile_Struct* m_epp);
LoadCharacterCurrency(uint32 character_id, PlayerProfile_Struct* pp);
LoadCharacterBindPoint(uint32 character_id, PlayerProfile_Struct* pp);
LoadCharacterMaterialColor(uint32 character_id, PlayerProfile_Struct* pp);
LoadCharacterBandolier(uint32 character_id, PlayerProfile_Struct* pp);
LoadCharacterTribute(uint32 character_id, PlayerProfile_Struct* pp);
LoadCharacterPotions(uint32 character_id, PlayerProfile_Struct* pp);
LoadCharacterLeadershipAA(uint32 character_id, PlayerProfile_Struct* pp);
- Saves: Occur all over the code now instead of calling full saves
SaveCharacterBindPoint(uint32 character_id, uint32 zone_id, uint32 instance_id, float x, float y, float z, float heading, uint8 is_home);
SaveCharacterCurrency(uint32 character_id, PlayerProfile_Struct* pp);
SaveCharacterData(uint32 character_id, uint32 account_id, PlayerProfile_Struct* pp, ExtendedProfile_Struct* m_epp);
SaveCharacterAA(uint32 character_id, uint32 aa_id, uint32 current_level);
SaveCharacterSpell(uint32 character_id, uint32 spell_id, uint32 slot_id);
SaveCharacterMemorizedSpell(uint32 character_id, uint32 spell_id, uint32 slot_id);
SaveCharacterMaterialColor(uint32 character_id, uint32 slot_id, uint32 color);
SaveCharacterSkill(uint32 character_id, uint32 skill_id, uint32 value);
SaveCharacterLanguage(uint32 character_id, uint32 lang_id, uint32 value);
SaveCharacterDisc(uint32 character_id, uint32 slot_id, uint32 disc_id);
SaveCharacterTribute(uint32 character_id, PlayerProfile_Struct* pp);
SaveCharacterBandolier(uint32 character_id, uint8 bandolier_id, uint8 bandolier_slot, uint32 item_id, uint32 icon, const char* bandolier_name);
SaveCharacterPotionBelt(uint32 character_id, uint8 potion_id, uint32 item_id, uint32 icon);
SaveCharacterLeadershipAA(uint32 character_id, PlayerProfile_Struct* pp);
- Deletes:
DeleteCharacterSpell(uint32 character_id, uint32 spell_id, uint32 slot_id);
DeleteCharacterMemorizedSpell(uint32 character_id, uint32 spell_id, uint32 slot_id);
DeleteCharacterDisc(uint32 character_id, uint32 slot_id);
DeleteCharacterBandolier(uint32 character_id, uint32 band_id);
DeleteCharacterLeadershipAAs(uint32 character_id);
- Now occur all over the code and only trigger when necessary
- Two FULL saves when looting a corpse, this has been reduced to just currency saves on initial loot and trimmed to one save since AddToMoneyPP did it already
- Every time a player moves coin with any situation (Splits/Trades/Merchant/Skills/Bank Coin Exchange/Coin Moves), a full save is made, this is now just a currency save
- Every time a player skilled up at a skill vendor, a full blob save hit was made, this is not just a currency hit
- Every time an AA was purchased, a full save was made
- Every time a spell was scribed/swapped, disc was trained
- When a client exists a zone, when a client enters a zone
- NOTE: These amount of excessive saves have caused scalability issues that cause the `character_` table to hang which causes process hangs that affect the whole server
because of the slowness of the `character_` table and the blob not allowing any indexing to occur
- All functions that once depended on the `character_` table are now rewritten to appropriately read from the `character_data` table
- Database query errors that occur during conversion or from and load/save/delete character functions are now leveraged via ThrowDBError and logs now go to
Server_Folder_Root/eqemu_query_error_log.txt (You cannot log errors natively through MySQL)
- DBASYNC IS NOW COMPLETELY REMOVED - This was mainly for Character data async loads/saves and merchantlist loads
- Side implementations:
Perl Exports:
- quest::crosszonesetentityvariablebynpctypeid(npctype_id, id, m_var) - Sets entity variables world wide with specified npctype_id
- quest::crosszonesignalnpcbynpctypeid(npctype_id, data) - Signals all NPC entities world wide with specified npctype_id
- $client->GetTaskActivityDoneCount(TaskID, ActivityID) - Gets task activity done count by task id and activity id for client entity
VIEW TABLE SIZE AFTER CONVERT:
SELECT CONCAT(table_schema, '.', table_name) as table_name,
CONCAT(ROUND(table_rows / 1000000, 2), 'M') rows,
CONCAT(ROUND(data_length / ( 1024 * 1024 * 1024 ), 2), 'G') DATA,
CONCAT(ROUND(index_length / ( 1024 * 1024 * 1024 ), 2), 'G') idx,
CONCAT(ROUND(( data_length + index_length ) / ( 1024 * 1024 * 1024 ), 2), 'G') total_size,
ROUND(index_length / data_length, 2) idxfrac
FROM information_schema.TABLES
WHERE `table_name` LIKE 'character_%'
ORDER BY DATA DESC;
== 09/20/2014 ==
demonstar55: Fix crash in SendEnterWorld on illegally long names
demonstar55: The client only lets you enter 15 characters for your name (UF at least)
demonstar55: Add rule Spells:SHDProcIDOffByOne for pre-UF spell file, set to true, UF+ set to false
KLS: #suspend and #ban now have required messages to record the reason for the ban/suspension.
== 09/19/2014 ==
demonstar55: Added Client::Tell_StringID (used in tell queue messages)
demonstar55: Tell queues (and offline) messages now show correctly
demonstar55: Fix starting with capital check
== 09/18/2014==
demonstar55: Implement tell queues
+3 -3
View File
@@ -8,7 +8,6 @@ SET(common_sources
crc16.cpp
crc32.cpp
database.cpp
dbasync.cpp
dbcore.cpp
debug.cpp
emu_opcodes.cpp
@@ -56,8 +55,9 @@ SET(common_sources
rulesys.cpp
serverinfo.cpp
shareddb.cpp
skills.cpp
spdat.cpp
string_util.cpp
string_util.cpp
struct_strategy.cpp
tcp_connection.cpp
tcp_server.cpp
@@ -103,8 +103,8 @@ SET(common_headers
crash.h
crc16.h
crc32.h
data_verification.h
database.h
dbasync.h
dbcore.h
debug.h
deity.h
+39 -5
View File
@@ -17,7 +17,8 @@ static const uint32 BIT_RoFAndLater = 0xFFFFFFE0;
static const uint32 BIT_RoF2AndLater = 0xFFFFFFC0;
static const uint32 BIT_AllClients = 0xFFFFFFFF;
typedef enum {
typedef enum
{
EQClientUnknown = 0,
EQClient62, // Build: 'Aug 4 2005 15:40:59'
EQClientTitanium, // Build: 'Oct 31 2005 10:33:37'
@@ -26,17 +27,50 @@ typedef enum {
EQClientUnderfoot, // Build: 'Jun 8 2010 16:44:32'
EQClientRoF, // Build: 'Dec 10 2012 17:35:44'
EQClientRoF2, // Build: 'May 10 2013 23:30:08'
_EQClientCount, // place new clients before this point (preferably, in release/attribute order)
// Values below are not implemented, as yet...
EmuNPC = _EQClientCount,
EmuMerc,
EmuBot,
EmuPet,
_EmuClientCount // array size for EQLimits
} EQClientVersion;
static const char* EQClientVersionName(EQClientVersion version)
{
switch (version)
{
case EQClientUnknown:
return "EQClientUnknown";
case EQClient62:
return "EQClient62";
case EQClientTitanium:
return "EQClientTitanium";
case EQClientSoF:
return "EQClientSoF";
case EQClientSoD:
return "EQClientSoD";
case EQClientUnderfoot:
return "EQClientUnderfoot";
case EQClientRoF:
return "EQClientRoF";
case EQClientRoF2:
return "EQClientRoF2";
case EmuNPC:
return "EmuNPC";
case EmuMerc:
return "EmuMerc";
case EmuBot:
return "EmuBot";
case EmuPet:
return "EmuPet";
default:
return "ERROR: Invalid EQClientVersion";
};
}
#endif /* CLIENTVERSIONS_H */
+48
View File
@@ -0,0 +1,48 @@
/* 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_DATA_VERIFICATION_H
#define COMMON_DATA_VERIFICATION_H
#include <algorithm>
namespace EQEmu
{
template <typename T>
T Clamp(const T& value, const T& lower, const T& upper) {
return std::max(lower, std::min(value, upper));
}
template <typename T>
T ClampLower(const T& value, const T& lower) {
return std::max(lower, value);
}
template <typename T>
T ClampUpper(const T& value, const T& upper) {
return std::min(value, upper);
}
template <typename T>
bool ValueWithin(const T& value, const T& lower, const T& upper) {
return value >= lower && value <= upper;
}
}
#endif
+1571 -519
View File
File diff suppressed because it is too large Load Diff
+9 -12
View File
@@ -26,12 +26,6 @@
#include "dbcore.h"
#include "linked_list.h"
#include "eq_packet_structs.h"
/*#include "eq_stream.h"
#include "guilds.h"
#include "misc_functions.h"
#include "mutex.h"
#include "item.h"
#include "extprofile.h"*/
#include <string>
#include <vector>
#include <map>
@@ -105,10 +99,16 @@ public:
Database(const char* host, const char* user, const char* passwd, const char* database,uint32 port);
bool Connect(const char* host, const char* user, const char* passwd, const char* database,uint32 port);
~Database();
bool ThrowDBError(std::string ErrorMessage, std::string query_title, std::string query);
/*
* General Character Related Stuff
*/
/* Character Creation */
bool SaveCharacterCreate(uint32 character_id, uint32 account_id, PlayerProfile_Struct* pp);
bool MoveCharacterToZone(const char* charname, const char* zonename);
bool MoveCharacterToZone(const char* charname, const char* zonename,uint32 zoneid);
bool MoveCharacterToZone(uint32 iCharID, const char* iZonename);
@@ -118,9 +118,8 @@ public:
bool AddToNameFilter(const char* name);
bool ReserveName(uint32 account_id, char* name);
bool CreateCharacter(uint32 account_id, char* name, uint16 gender, uint16 race, uint16 class_, uint8 str, uint8 sta, uint8 cha, uint8 dex, uint8 int_, uint8 agi, uint8 wis, uint8 face);
bool StoreCharacter(uint32 account_id, PlayerProfile_Struct* pp, Inventory* inv, ExtendedProfile_Struct *ext);
bool StoreCharacter(uint32 account_id, PlayerProfile_Struct* pp, Inventory* inv);
bool DeleteCharacter(char* name);
uint8 CopyCharacter(const char* oldname, const char* newname, uint32 acctid);
/*
* General Information Getting Queries
@@ -217,6 +216,8 @@ public:
uint32 GetRaidID(const char* name);
const char *GetRaidLeaderName(uint32 rid);
bool CheckDatabaseConversions();
/*
* Database Variables
*/
@@ -250,10 +251,6 @@ public:
void SetLoginFlags(uint32 CharID, bool LFP, bool LFG, uint8 firstlogon);
void AddReport(std::string who, std::string against, std::string lines);
protected:
void HandleMysqlError(uint32 errnum);
private:
void DBInitVars();
-669
View File
@@ -1,669 +0,0 @@
#include "debug.h"
#ifdef _WINDOWS
#include <windows.h>
#include <process.h>
#include <winsock2.h>
#endif
#include <iostream>
#include "dbasync.h"
#include "database.h"
#include <errmsg.h>
#include <mysqld_error.h>
#include <limits.h>
#include "dbcore.h"
#include <string.h>
//#include "../common/misc_functions.h"
#include "string_util.h"
#define ASYNC_LOOP_GRANULARITY 4 //# of ms between checking our work
bool DBAsyncCB_LoadVariables(DBAsyncWork* iWork) {
char errbuf[MYSQL_ERRMSG_SIZE];
MYSQL_RES* result = 0;
DBAsyncQuery* dbaq = iWork->PopAnswer();
if (dbaq->GetAnswer(errbuf, &result))
iWork->GetDB()->LoadVariables_result(result);
else
std::cout << "Error: DBAsyncCB_LoadVariables failed: !GetAnswer: '" << errbuf << "'" << std::endl;
return true;
}
void AsyncLoadVariables(DBAsync *dba, Database *db) {
char* query = 0;
DBAsyncWork* dbaw = new DBAsyncWork(db, &DBAsyncCB_LoadVariables, 0, DBAsync::Read);
dbaw->AddQuery(0, &query, db->LoadVariables_MQ(&query));
dba->AddWork(&dbaw);
}
//we only need to do anything when somebody puts work on the queue
//so instead of checking all the time, we will wait on a condition
//which will get signaled when somebody puts something on the queue
ThreadReturnType DBAsyncLoop(void* tmp) {
DBAsync* dba = (DBAsync*) tmp;
#ifndef WIN32
_log(COMMON__THREADS, "Starting DBAsyncLoop with thread ID %d", pthread_self());
#endif
dba->MLoopRunning.lock();
while (dba->RunLoop()) {
//wait before working so we check the loop condition
//as soon as were done working
dba->CInList.Wait();
//we could check dba->RunLoop() again to see if we
//got turned off while we were waiting
{
dba->Process();
}
}
dba->MLoopRunning.unlock();
#ifndef WIN32
_log(COMMON__THREADS, "Ending DBAsyncLoop with thread ID %d", pthread_self());
#endif
THREAD_RETURN(nullptr);
}
DBAsync::DBAsync(DBcore* iDBC)
: Timeoutable(10000)
{
pDBC = iDBC;
pRunLoop = true;
pNextID = 1;
#ifdef _WINDOWS
_beginthread(DBAsyncLoop, 0, this);
#else
pthread_t thread;
pthread_create(&thread, nullptr, DBAsyncLoop, this);
#endif
}
DBAsync::~DBAsync() {
StopThread();
}
bool DBAsync::StopThread() {
bool ret;
MRunLoop.lock();
ret = pRunLoop;
pRunLoop = false;
MRunLoop.unlock();
//signal the condition so we exit the loop if were waiting
CInList.Signal();
//this effectively waits for the processing thread to finish
MLoopRunning.lock();
MLoopRunning.unlock();
return ret;
}
uint32 DBAsync::AddWork(DBAsyncWork** iWork, uint32 iDelay) {
MInList.lock();
uint32 ret = GetNextID();
if (!(*iWork)->SetWorkID(ret)) {
MInList.unlock();
return 0;
}
InList.Append(*iWork);
(*iWork)->SetStatus(Queued);
if (iDelay)
(*iWork)->pExecuteAfter = Timer::GetCurrentTime() + iDelay;
#if DEBUG_MYSQL_QUERIES >= 2
std::cout << "Adding AsyncWork #" << (*iWork)->GetWorkID() << std::endl;
std::cout << "ExecuteAfter = " << (*iWork)->pExecuteAfter << " (" << Timer::GetCurrentTime() << " + " << iDelay << ")" << std::endl;
#endif
*iWork = 0;
MInList.unlock();
//wake up the processing thread and tell it to get to work.
CInList.Signal();
return ret;
}
bool DBAsync::CancelWork(uint32 iWorkID) {
if (iWorkID == 0)
return false;
#if DEBUG_MYSQL_QUERIES >= 2
std::cout << "DBAsync::CancelWork: " << iWorkID << std::endl;
#endif
MCurrentWork.lock();
if (CurrentWork && CurrentWork->GetWorkID() == iWorkID) {
CurrentWork->Cancel();
MCurrentWork.unlock();
return true;
}
MCurrentWork.unlock();
MInList.lock();
LinkedListIterator<DBAsyncWork*> iterator(InList);
iterator.Reset();
while (iterator.MoreElements()) {
if (iterator.GetData()->GetWorkID() == iWorkID) {
iterator.RemoveCurrent(true);
MInList.unlock();
return true;
}
iterator.Advance();
}
MInList.unlock();
return false;
}
bool DBAsync::RunLoop() {
bool ret;
MRunLoop.lock();
ret = pRunLoop;
MRunLoop.unlock();
return ret;
}
DBAsyncWork* DBAsync::InListPop() {
DBAsyncWork* ret = 0;
MInList.lock();
LinkedListIterator<DBAsyncWork*> iterator(InList);
iterator.Reset();
while (iterator.MoreElements()) {
if (iterator.GetData()->pExecuteAfter <= Timer::GetCurrentTime()) {
ret = iterator.GetData();
#if DEBUG_MYSQL_QUERIES >= 2
std::cout << "Poping AsyncWork #" << ret->GetWorkID() << std::endl;
std::cout << ret->pExecuteAfter << " <= " << Timer::GetCurrentTime() << std::endl;
#endif
iterator.RemoveCurrent(false);
break;
}
iterator.Advance();
}
MInList.unlock();
return ret;
}
DBAsyncWork* DBAsync::InListPopWrite() {
MInList.lock();
LinkedListIterator<DBAsyncWork*> iterator(InList);
DBAsyncWork* ret = 0;
DBAsync::Type tmpType;
iterator.Reset();
while (iterator.MoreElements()) {
tmpType = iterator.GetData()->Type();
if (tmpType == Write || tmpType == Both) {
ret = iterator.GetData();
iterator.RemoveCurrent(false);
break;
}
iterator.Advance();
}
MInList.unlock();
return ret;
}
void DBAsync::AddFQ(DBAsyncFinishedQueue* iDBAFQ) {
MFQList.lock();
DBAsyncFinishedQueue** tmp = new DBAsyncFinishedQueue*;
*tmp = iDBAFQ;
FQList.Append(tmp);
MFQList.unlock();
}
void DBAsync::Process() {
DBAsyncWork* tmpWork;
MCurrentWork.lock();
while ((CurrentWork = InListPop())) {
MCurrentWork.unlock();
//move from queued to executing
Status tmpStatus = CurrentWork->SetStatus(Executing);
if (tmpStatus == Queued) {
//execute the work
ProcessWork(CurrentWork);
tmpWork = CurrentWork;
MCurrentWork.lock();
CurrentWork = 0;
MCurrentWork.unlock();
//move from executing to finished
tmpStatus = tmpWork->SetStatus(DBAsync::Finished);
if (tmpStatus != Executing) {
if (tmpStatus != Canceled) {
std::cout << "Error: Unexpected DBAsyncWork->Status in DBAsync::Process #1" << std::endl;
}
MCurrentWork.lock();
safe_delete(tmpWork);
}
else {
//call callbacks or put results on finished queue
DispatchWork(tmpWork);
Sleep(25);
MCurrentWork.lock();
}
}
else {
if (tmpStatus != Canceled) {
std::cout << "Error: Unexpected DBAsyncWork->Status in DBAsync::Process #2" << std::endl;
}
MCurrentWork.lock();
safe_delete(CurrentWork);
}
}
MCurrentWork.unlock();
}
void DBAsync::CheckTimeout() {
try{
MFQList.lock();
LinkedListIterator<DBAsyncFinishedQueue**> iterator(FQList);
iterator.Reset();
while (iterator.MoreElements()) {
(*iterator.GetData())->CheckTimeouts();
iterator.Advance();
}
MFQList.unlock();
}
catch(...){
}
}
void DBAsync::CommitWrites() {
#if DEBUG_MYSQL_QUERIES >= 2
std::cout << "DBAsync::CommitWrites() called." << std::endl;
#endif
DBAsyncWork* tmpWork;
while ((tmpWork = InListPopWrite())) {
Status tmpStatus = tmpWork->SetStatus(Executing);
if (tmpStatus == Queued) {
ProcessWork(tmpWork);
tmpStatus = tmpWork->SetStatus(DBAsync::Finished);
if (tmpStatus != Executing) {
if (tmpStatus != Canceled) {
std::cout << "Error: Unexpected DBAsyncWork->Status in DBAsync::CommitWrites #1" << std::endl;
}
safe_delete(tmpWork);
}
else {
DispatchWork(tmpWork);
}
}
else {
if (tmpStatus != Canceled) {
std::cout << "Error: Unexpected DBAsyncWork->Status in DBAsync::CommitWrites #2" << std::endl;
}
safe_delete(tmpWork);
}
}
}
void DBAsync::ProcessWork(DBAsyncWork* iWork, bool iSleep) {
DBAsyncQuery* CurrentQuery;
while ((CurrentQuery = iWork->PopQuery())) {
CurrentQuery->Process(pDBC);
iWork->PushAnswer(CurrentQuery);
if (iSleep)
Sleep(1);
}
}
void DBAsync::DispatchWork(DBAsyncWork* iWork) {
//if this work has a callback, call it
//otherwise, stick the work on the finish queue
if (iWork->pCB) {
if (iWork->pCB(iWork))
safe_delete(iWork);
}
else {
if (!iWork->pDBAFQ->Push(iWork))
safe_delete(iWork);
}
}
DBAsyncFinishedQueue::DBAsyncFinishedQueue(uint32 iTimeout) {
pTimeout = iTimeout;
}
DBAsyncFinishedQueue::~DBAsyncFinishedQueue() {
}
void DBAsyncFinishedQueue::CheckTimeouts() {
if (pTimeout == 0xFFFFFFFF)
return;
MLock.lock();
LinkedListIterator<DBAsyncWork*> iterator(list);
iterator.Reset();
while (iterator.MoreElements()) {
if (iterator.GetData()->CheckTimeout(pTimeout))
iterator.RemoveCurrent(true);
iterator.Advance();
}
MLock.unlock();
}
DBAsyncWork* DBAsyncFinishedQueue::Pop() {
DBAsyncWork* ret = 0;
MLock.lock();
ret = list.Pop();
MLock.unlock();
return ret;
}
DBAsyncWork* DBAsyncFinishedQueue::Find(uint32 iWorkID) {
DBAsyncWork* ret = 0;
MLock.lock();
LinkedListIterator<DBAsyncWork*> iterator(list);
iterator.Reset();
while (iterator.MoreElements()) {
if (iterator.GetData()->GetWorkID() == iWorkID) {
ret = iterator.GetData();
iterator.RemoveCurrent(false);
break;
}
iterator.Advance();
}
MLock.unlock();
return ret;
}
DBAsyncWork* DBAsyncFinishedQueue::PopByWPT(uint32 iWPT) {
DBAsyncWork* ret = 0;
MLock.lock();
LinkedListIterator<DBAsyncWork*> iterator(list);
iterator.Reset();
while (iterator.MoreElements()) {
if (iterator.GetData()->WPT() == iWPT) {
ret = iterator.GetData();
iterator.RemoveCurrent(false);
break;
}
iterator.Advance();
}
MLock.unlock();
return ret;
}
bool DBAsyncFinishedQueue::Push(DBAsyncWork* iDBAW) {
if (!this)
return false;
MLock.lock();
list.Append(iDBAW);
MLock.unlock();
return true;
}
DBAsyncWork::DBAsyncWork(Database *db, DBAsyncFinishedQueue* iDBAFQ, uint32 iWPT, DBAsync::Type iType, uint32 iTimeout)
: m_db(db)
{
pstatus = DBAsync::AddingWork;
pType = iType;
pExecuteAfter = 0;
pWorkID = 0;
pDBAFQ = iDBAFQ;
pCB = 0;
pWPT = iWPT;
pQuestionCount = 0;
pAnswerCount = 0;
pTimeout = iTimeout;
pTSFinish = 0;
}
DBAsyncWork::DBAsyncWork(Database *db, DBWorkCompleteCallBack iCB, uint32 iWPT, DBAsync::Type iType, uint32 iTimeout)
: m_db(db)
{
pstatus = DBAsync::AddingWork;
pType = iType;
pExecuteAfter = 0;
pWorkID = 0;
pDBAFQ = 0;
pCB = iCB;
pWPT = iWPT;
pQuestionCount = 0;
pAnswerCount = 0;
pTimeout = iTimeout;
pTSFinish = 0;
}
DBAsyncWork::~DBAsyncWork() {
DBAsyncQuery* dbaq = 0;
while ((dbaq = todo.pop()))
safe_delete(dbaq);
while ((dbaq = done.pop()))
safe_delete(dbaq);
while ((dbaq = todel.pop()))
safe_delete(dbaq);
}
bool DBAsyncWork::AddQuery(DBAsyncQuery** iDBAQ) {
bool ret;
MLock.lock();
if (pstatus != DBAsync::AddingWork)
ret = false;
else {
ret = true;
pQuestionCount++;
todo.push(*iDBAQ);
(*iDBAQ)->pstatus = DBAsync::Queued;
*iDBAQ = 0;
}
MLock.unlock();
return ret;
}
bool DBAsyncWork::AddQuery(uint32 iQPT, char** iQuery, uint32 iQueryLen, bool iGetResultSet, bool iGetErrbuf) {
DBAsyncQuery* DBAQ = new DBAsyncQuery(iQPT, iQuery, iQueryLen, iGetResultSet, iGetErrbuf);
if (AddQuery(&DBAQ))
return true;
else {
safe_delete(DBAQ);
return false;
}
}
bool DBAsyncWork::SetWorkID(uint32 iWorkID) {
bool ret = true;
MLock.lock();
if (pWorkID)
ret = false;
else
pWorkID = iWorkID;
MLock.unlock();
return ret;
}
uint32 DBAsyncWork::GetWorkID() {
uint32 ret;
MLock.lock();
ret = pWorkID;
MLock.unlock();
return ret;
}
uint32 DBAsyncWork::WPT() {
uint32 ret;
MLock.lock();
ret = pWPT;
MLock.unlock();
return ret;
}
DBAsync::Type DBAsyncWork::Type() {
DBAsync::Type ret;
MLock.lock();
ret = pType;
MLock.unlock();
return ret;
}
DBAsyncQuery* DBAsyncWork::PopAnswer() {
DBAsyncQuery* ret;
MLock.lock();
ret = done.pop();
if (ret)
pAnswerCount--;
todel.push(ret);
MLock.unlock();
return ret;
}
bool DBAsyncWork::CheckTimeout(uint32 iFQTimeout) {
if (pTimeout == 0xFFFFFFFF)
return false;
bool ret = false;
MLock.lock();
if (pTimeout > iFQTimeout)
iFQTimeout = pTimeout;
if (Timer::GetCurrentTime() > (pTSFinish + iFQTimeout))
ret = true;
MLock.unlock();
return ret;
}
//sets the work's status to the supplied value and returns
//the revious status
DBAsync::Status DBAsyncWork::SetStatus(DBAsync::Status iStatus) {
DBAsync::Status ret;
MLock.lock();
if (iStatus == DBAsync::Finished)
pTSFinish = Timer::GetCurrentTime();
ret = pstatus;
pstatus = iStatus;
MLock.unlock();
return ret;
}
bool DBAsyncWork::Cancel() {
bool ret;
MLock.lock();
if (pstatus != DBAsync::Finished) {
pstatus = DBAsync::Canceled;
ret = true;
}
else
ret = false;
MLock.unlock();
return ret;
}
bool DBAsyncWork::IsCancled() {
bool ret;
MLock.lock();
ret = (bool) (pstatus == DBAsync::Canceled);
MLock.unlock();
return ret;
}
DBAsyncQuery* DBAsyncWork::PopQuery() {
DBAsyncQuery* ret = 0;
MLock.lock();
ret = todo.pop();
if (ret)
pQuestionCount--;
MLock.unlock();
return ret;
}
void DBAsyncWork::PushAnswer(DBAsyncQuery* iDBAQ) {
MLock.lock();
done.push(iDBAQ);
pAnswerCount++;
MLock.unlock();
}
DBAsyncQuery::DBAsyncQuery(uint32 iQPT, char** iQuery, uint32 iQueryLen, bool iGetResultSet, bool iGetErrbuf) {
if (iQueryLen == 0xFFFFFFFF)
pQueryLen = strlen(*iQuery);
else
pQueryLen = iQueryLen;
pQuery = *iQuery;
*iQuery = 0;
Init(iQPT, iGetResultSet, iGetErrbuf);
}
DBAsyncQuery::DBAsyncQuery(uint32 iQPT, const char* iQuery, uint32 iQueryLen, bool iGetResultSet, bool iGetErrbuf) {
if (iQueryLen == 0xFFFFFFFF)
pQueryLen = strlen(iQuery);
else
pQueryLen = iQueryLen;
pQuery = strn0cpy(new char[pQueryLen+1], iQuery, pQueryLen+1);
Init(iQPT, iGetResultSet, iGetErrbuf);
}
void DBAsyncQuery::Init(uint32 iQPT, bool iGetResultSet, bool iGetErrbuf) {
pstatus = DBAsync::AddingWork;
pQPT = iQPT;
pGetResultSet = iGetResultSet;
pGetErrbuf = iGetErrbuf;
pmysqlsuccess = false;
perrbuf = 0;
perrnum = 0;
presult = 0;
paffected_rows = 0;
plast_insert_id = 0;
}
DBAsyncQuery::~DBAsyncQuery() {
safe_delete_array(perrbuf);
safe_delete_array(pQuery);
if (presult)
mysql_free_result(presult);
}
bool DBAsyncQuery::GetAnswer(char* errbuf, MYSQL_RES** result, uint32* affected_rows, uint32* last_insert_id, uint32* errnum) {
if (pstatus != DBAsync::Finished) {
if (errbuf)
snprintf(errbuf, MYSQL_ERRMSG_SIZE, "Error: Query not finished.");
if (errnum)
*errnum = UINT_MAX;
return false;
}
if (errbuf) {
if (pGetErrbuf) {
if (perrbuf)
strn0cpy(errbuf, perrbuf, MYSQL_ERRMSG_SIZE);
else
snprintf(errbuf, MYSQL_ERRMSG_SIZE, "Error message should've been saved, but hasnt. errno: %u", perrnum);
}
else
snprintf(errbuf, MYSQL_ERRMSG_SIZE, "Error message not saved. errno: %u", perrnum);
}
if (errnum)
*errnum = perrnum;
if (affected_rows)
*affected_rows = paffected_rows;
if (last_insert_id)
*last_insert_id = plast_insert_id;
if (result)
*result = presult;
return pmysqlsuccess;
}
void DBAsyncQuery::Process(DBcore* iDBC) {
pstatus = DBAsync::Executing;
if (pGetErrbuf)
perrbuf = new char[MYSQL_ERRMSG_SIZE];
MYSQL_RES** resultPP = 0;
if (pGetResultSet)
resultPP = &presult;
pmysqlsuccess = iDBC->RunQuery(pQuery, pQueryLen, perrbuf, resultPP, &paffected_rows, &plast_insert_id, &perrnum);
pstatus = DBAsync::Finished;
}
-176
View File
@@ -1,176 +0,0 @@
#ifndef DBASYNC_H
#define DBASYNC_H
#include "../common/dbcore.h"
#include "../common/timeoutmgr.h"
class DBAsyncFinishedQueue;
class DBAsyncWork;
class DBAsyncQuery;
class Database;
// Big daddy that owns the threads and does the work
class DBAsync : private Timeoutable {
public:
enum Status { AddingWork, Queued, Executing, Finished, Canceled };
enum Type { Read, Write, Both };
DBAsync(DBcore* iDBC);
~DBAsync();
bool StopThread();
uint32 AddWork(DBAsyncWork** iWork, uint32 iDelay = 0);
bool CancelWork(uint32 iWorkID);
void CommitWrites();
void AddFQ(DBAsyncFinishedQueue* iDBAFQ);
protected:
//things related to the processing thread:
friend ThreadReturnType DBAsyncLoop(void* tmp);
Mutex MLoopRunning;
Condition CInList;
bool RunLoop();
void Process();
private:
virtual void CheckTimeout();
void ProcessWork(DBAsyncWork* iWork, bool iSleep = true);
void DispatchWork(DBAsyncWork* iWork);
inline uint32 GetNextID() { return pNextID++; }
DBAsyncWork* InListPop();
DBAsyncWork* InListPopWrite(); // Ignores delay
void OutListPush(DBAsyncWork* iDBAW);
Mutex MRunLoop;
bool pRunLoop;
DBcore* pDBC;
uint32 pNextID;
Mutex MInList;
LinkedList<DBAsyncWork*> InList;
Mutex MFQList;
LinkedList<DBAsyncFinishedQueue**> FQList;
// Mutex for outside access to current work & when current work is being changed.
// NOT locked when CurrentWork is being accessed by the DBAsync thread.
// Never change pointer from outside DBAsync thread!
// Only here for access to thread-safe DBAsyncWork functions.
Mutex MCurrentWork;
DBAsyncWork* CurrentWork;
};
/*
DB Work Complete Callback:
This will be called under the DBAsync thread! Never access any non-threadsafe
data/functions/classes. (ie: zone, entitylist, client, etc are not threadsafe)
Function prototype:
return value: true if we should delete the data, false if we should keep it
*/
typedef bool(*DBWorkCompleteCallBack)(DBAsyncWork*);
class DBAsyncFinishedQueue {
public:
DBAsyncFinishedQueue(uint32 iTimeout = 90000);
~DBAsyncFinishedQueue();
DBAsyncWork* Pop();
DBAsyncWork* PopByWPT(uint32 iWPT);
DBAsyncWork* Find(uint32 iWPT);
bool Push(DBAsyncWork* iDBAW);
void CheckTimeouts();
private:
Mutex MLock;
uint32 pTimeout;
LinkedList<DBAsyncWork*> list;
};
// Container class for multiple queries
class DBAsyncWork {
public:
DBAsyncWork(Database *db, DBAsyncFinishedQueue* iDBAFQ, uint32 iWPT = 0, DBAsync::Type iType = DBAsync::Both, uint32 iTimeout = 0);
DBAsyncWork(Database *db, DBWorkCompleteCallBack iCB, uint32 iWPT = 0, DBAsync::Type iType = DBAsync::Both, uint32 iTimeout = 0);
~DBAsyncWork();
bool AddQuery(DBAsyncQuery** iDBAQ);
bool AddQuery(uint32 iQPT, char** iQuery, uint32 iQueryLen = 0xFFFFFFFF, bool iGetResultSet = true, bool iGetErrbuf = true);
uint32 WPT();
DBAsync::Type Type();
// Pops finished queries off the work
DBAsyncQuery* PopAnswer();
uint32 QueryCount();
Database *GetDB() const { return(m_db); }
bool CheckTimeout(uint32 iFQTimeout);
bool SetWorkID(uint32 iWorkID);
uint32 GetWorkID();
protected:
friend class DBAsync;
DBAsync::Status SetStatus(DBAsync::Status iStatus);
bool Cancel();
bool IsCancled();
DBAsyncQuery* PopQuery(); // Get query to be run
void PushAnswer(DBAsyncQuery* iDBAQ); // Push answer back into workset
// not mutex'd cause only to be accessed from dbasync class
uint32 pExecuteAfter;
private:
Mutex MLock;
uint32 pQuestionCount;
uint32 pAnswerCount;
uint32 pWorkID;
uint32 pWPT;
uint32 pTimeout;
uint32 pTSFinish; // timestamp when finished
DBAsyncFinishedQueue* pDBAFQ; //we do now own this pointer
DBWorkCompleteCallBack pCB;
DBAsync::Status pstatus;
DBAsync::Type pType;
MyQueue<DBAsyncQuery> todo;
MyQueue<DBAsyncQuery> done;
MyQueue<DBAsyncQuery> todel;
Database *const m_db; //we do now own this pointer
};
// Container class for the query information
class DBAsyncQuery {
public:
DBAsyncQuery(uint32 iQPT, char** iQuery, uint32 iQueryLen = 0xFFFFFFFF, bool iGetResultSet = true, bool iGetErrbuf = true);
DBAsyncQuery(uint32 iQPT, const char* iQuery, uint32 iQueryLen = 0xFFFFFFFF, bool iGetResultSet = true, bool iGetErrbuf = true);
~DBAsyncQuery();
bool GetAnswer(char* errbuf = 0, MYSQL_RES** result = 0, uint32* affected_rows = 0, uint32* last_insert_id = 0, uint32* errnum = 0);
inline uint32 QPT() { return pQPT; }
protected:
friend class DBAsyncWork;
uint32 pQPT;
friend class DBAsync;
void Process(DBcore* iDBC);
void Init(uint32 iQPT, bool iGetResultSet, bool iGetErrbuf);
DBAsync::Status pstatus;
char* pQuery;
uint32 pQueryLen;
bool pGetResultSet;
bool pGetErrbuf;
bool pmysqlsuccess;
char* perrbuf;
uint32 perrnum;
uint32 paffected_rows;
uint32 plast_insert_id;
MYSQL_RES* presult;
};
void AsyncLoadVariables(DBAsync *dba, Database *db);
#endif
+10 -8
View File
@@ -80,14 +80,15 @@ public:
~EQEMuLog();
enum LogIDs {
Status = 0, //this must stay the first entry in this list
Normal,
Error,
Debug,
Quest,
Commands,
Crash,
MaxLogID
Status = 0, /* This must stay the first entry in this list */
Normal, /* Normal Logs */
Error, /* Error Logs */
Debug, /* Debug Logs */
Quest, /* Quest Logs */
Commands, /* Issued Comamnds */
Crash, /* Crash Logs */
Save, /* Client Saves */
MaxLogID /* Max, used in functions to get the max log ID */
};
//these are callbacks called for each
@@ -113,6 +114,7 @@ private:
Mutex MOpen;
Mutex MLog[MaxLogID];
FILE* fp[MaxLogID];
/* LogStatus: bitwise variable
1 = output to file
2 = output to stdout
+504 -502
View File
File diff suppressed because it is too large Load Diff
+20
View File
@@ -1024,6 +1024,26 @@ bool EQLimits::AllowsEmptyBagInBag(uint32 version) {
//return local[ValidateMobVersion(version)];
}
bool EQLimits::AllowsClickCastFromBag(uint32 version) {
static const bool local[_EmuClientCount] = {
/*Unknown*/ false,
/*62*/ Client62::limits::ALLOWS_CLICK_CAST_FROM_BAG,
/*Titanium*/ Titanium::limits::ALLOWS_CLICK_CAST_FROM_BAG,
/*SoF*/ SoF::limits::ALLOWS_CLICK_CAST_FROM_BAG,
/*SoD*/ SoD::limits::ALLOWS_CLICK_CAST_FROM_BAG,
/*Underfoot*/ Underfoot::limits::ALLOWS_CLICK_CAST_FROM_BAG,
/*RoF*/ RoF::limits::ALLOWS_CLICK_CAST_FROM_BAG,
/*RoF2*/ false,
/*NPC*/ false,
/*Merc*/ false,
/*Bot*/ false,
/*Pet*/ false
};
return local[ValidateMobVersion(version)];
}
// items
uint16 EQLimits::ItemCommonSize(uint32 version) {
static const uint16 local[_EmuClientCount] = {
+1
View File
@@ -184,6 +184,7 @@ public:
static uint64 CursorBitmask(uint32 version);
static bool AllowsEmptyBagInBag(uint32 version);
static bool AllowsClickCastFromBag(uint32 version);
// items
static uint16 ItemCommonSize(uint32 version);
+9 -6
View File
@@ -97,16 +97,15 @@ protected:
};
class EQApplicationPacket : public EQPacket {
// friend class EQProtocolPacket;
friend class EQStream;
public:
EQApplicationPacket() : EQPacket(OP_Unknown,nullptr,0)
EQApplicationPacket() : EQPacket(OP_Unknown, nullptr, 0), opcode_bypass(0)
{ app_opcode_size = GetExecutablePlatform() == ExePlatformUCS ? 1 : 2; }
EQApplicationPacket(const EmuOpcode op) : EQPacket(op,nullptr,0)
EQApplicationPacket(const EmuOpcode op) : EQPacket(op, nullptr, 0), opcode_bypass(0)
{ app_opcode_size = GetExecutablePlatform() == ExePlatformUCS ? 1 : 2; }
EQApplicationPacket(const EmuOpcode op, const uint32 len) : EQPacket(op,nullptr,len)
EQApplicationPacket(const EmuOpcode op, const uint32 len) : EQPacket(op, nullptr, len), opcode_bypass(0)
{ app_opcode_size = GetExecutablePlatform() == ExePlatformUCS ? 1 : 2; }
EQApplicationPacket(const EmuOpcode op, const unsigned char *buf, const uint32 len) : EQPacket(op,buf,len)
EQApplicationPacket(const EmuOpcode op, const unsigned char *buf, const uint32 len) : EQPacket(op, buf, len), opcode_bypass(0)
{ app_opcode_size = GetExecutablePlatform() == ExePlatformUCS ? 1 : 2; }
bool combine(const EQApplicationPacket *rhs);
uint32 serialize (uint16 opcode, unsigned char *dest) const;
@@ -119,12 +118,16 @@ public:
virtual void DumpRawHeader(uint16 seq=0xffff, FILE *to = stdout) const;
virtual void DumpRawHeaderNoTime(uint16 seq=0xffff, FILE *to = stdout) const;
uint16 GetOpcodeBypass() { return opcode_bypass; }
void SetOpcodeBypass(uint16 v) { opcode_bypass = v; }
protected:
uint8 app_opcode_size;
uint16 opcode_bypass;
private:
EQApplicationPacket(const EQApplicationPacket &p) : EQPacket(p.emu_opcode, p.pBuffer, p.size) { app_opcode_size = p.app_opcode_size; }
EQApplicationPacket(const EQApplicationPacket &p) : EQPacket(p.emu_opcode, p.pBuffer, p.size), opcode_bypass(p.opcode_bypass) { app_opcode_size = p.app_opcode_size; }
};
+10 -7
View File
@@ -800,9 +800,12 @@ struct SuspendedMinion_Struct
** Length: 4308 bytes
** OpCode: 0x006a
*/
static const uint32 MAX_PP_LANGUAGE = 28;
static const uint32 MAX_PP_SPELLBOOK = 480; // Increased to 480 to support SoF
static const uint32 MAX_PP_MEMSPELL = 9;
static const uint32 MAX_PP_LANGUAGE = 28;
static const uint32 MAX_PP_SPELLBOOK = 480; // Set for all functions
static const uint32 MAX_PP_MEMSPELL = 9; // Set to latest client so functions can work right
static const uint32 MAX_PP_REF_SPELLBOOK = 480; // Set for Player Profile size retain
static const uint32 MAX_PP_REF_MEMSPELL = 9; // Set for Player Profile size retain
static const uint32 MAX_PP_SKILL = _SkillPacketArraySize; // 100 - actual skills buffer size
static const uint32 MAX_PP_AA_ARRAY = 240;
static const uint32 MAX_GROUP_MEMBERS = 6;
@@ -880,7 +883,7 @@ struct PlayerProfile_Struct
/*0245*/ uint8 guildbanker;
/*0246*/ uint8 unknown0246[6]; //
/*0252*/ uint32 intoxication;
/*0256*/ uint32 spellSlotRefresh[MAX_PP_MEMSPELL]; //in ms
/*0256*/ uint32 spellSlotRefresh[MAX_PP_REF_MEMSPELL]; //in ms
/*0292*/ uint32 abilitySlotRefresh;
/*0296*/ uint8 haircolor; // Player hair color
/*0297*/ uint8 beardcolor; // Player beard color
@@ -919,9 +922,9 @@ struct PlayerProfile_Struct
/*2505*/ uint8 unknown2541[47]; // ?
/*2552*/ uint8 languages[MAX_PP_LANGUAGE];
/*2580*/ uint8 unknown2616[4];
/*2584*/ uint32 spell_book[MAX_PP_SPELLBOOK];
/*2584*/ uint32 spell_book[MAX_PP_REF_SPELLBOOK];
/*4504*/ uint8 unknown4540[128]; // Was [428] all 0xff
/*4632*/ uint32 mem_spells[MAX_PP_MEMSPELL];
/*4632*/ uint32 mem_spells[MAX_PP_REF_MEMSPELL];
/*4668*/ uint8 unknown4704[32]; //
/*4700*/ float y; // Player y position
/*4704*/ float x; // Player x position
@@ -4064,7 +4067,7 @@ struct GroupInvite_Struct {
// uint8 unknown128[65];
};
struct BuffFadeMsg_Struct {
struct ColoredText_Struct {
uint32 color;
char msg[1];
};
+6 -48
View File
@@ -532,9 +532,12 @@ void EQStream::FastQueuePacket(EQApplicationPacket **p, bool ack_req)
return;
}
uint16 opcode = (*OpMgr)->EmuToEQ(pack->emu_opcode);
//_log(NET__APP_TRACE, "Queueing %sacked packet with opcode 0x%x (%s) and length %d", ack_req?"":"non-", opcode, OpcodeManager::EmuToName(pack->emu_opcode), pack->size);
uint16 opcode = 0;
if(pack->GetOpcodeBypass() != 0) {
opcode = pack->GetOpcodeBypass();
} else {
opcode = (*OpMgr)->EmuToEQ(pack->emu_opcode);
}
if (!ack_req) {
NonSequencedPush(new EQProtocolPacket(opcode, pack->pBuffer, pack->size));
@@ -877,43 +880,6 @@ sockaddr_in address;
AddBytesSent(length);
}
/*
commented out since im not sure theres a lot of merit in it.
Really it was bitterness towards allocating a 2k buffer on the stack each call.
Im sure the thought was client side, but even then, they will
likely need a whole thread to call this method, in which case, they should
supply the buffer so we dont re-allocate it each time.
EQProtocolPacket *EQStream::Read(int eq_fd, sockaddr_in *from)
{
int socklen;
int length=0;
EQProtocolPacket *p=nullptr;
char temp[15];
socklen=sizeof(sockaddr);
#ifdef _WINDOWS
length=recvfrom(eq_fd, (char *)_tempBuffer, 2048, 0, (struct sockaddr*)from, (int *)&socklen);
#else
length=recvfrom(eq_fd, _tempBuffer, 2048, 0, (struct sockaddr*)from, (socklen_t *)&socklen);
#endif
if (length>=2) {
p=new EQProtocolPacket(_tempBuffer[1],&_tempBuffer[2],length-2);
uint32 ip=from->sin_addr.s_addr;
sprintf(temp,"%d.%d.%d.%d:%d",
*(unsigned char *)&ip,
*((unsigned char *)&ip+1),
*((unsigned char *)&ip+2),
*((unsigned char *)&ip+3),
ntohs(from->sin_port));
//std::cout << timestamp() << "Data from: " << temp << " OpCode 0x" << std::hex << std::setw(2) << std::setfill('0') << (int)p->opcode << std::dec << std::endl;
//dump_message(p->pBuffer,p->size,timestamp());
}
return p;
}*/
void EQStream::SendSessionResponse()
{
EQProtocolPacket *out=new EQProtocolPacket(OP_SessionResponse,nullptr,sizeof(SessionResponse));
@@ -1101,14 +1067,6 @@ EQProtocolPacket *p=nullptr;
SequencedQueue.clear();
}
MOutboundQueue.unlock();
/*if(uint16(SequencedBase + SequencedQueue.size()) != NextOutSeq) {
_log(NET__ERROR, _L "Out-bound Invalid Sequenced queue: BS %d + SQ %d != NOS %d" __L, SequencedBase, SequencedQueue.size(), NextOutSeq);
}
if(NextSequencedSend > SequencedQueue.size()) {
_log(NET__ERROR, _L "Out-bound Next Send Sequence is beyond the end of the queue NSS %d > SQ %d" __L, NextSequencedSend, SequencedQueue.size());
}*/
//NOTE: we prolly want to reset counters if we are stupposed to do anything after this.
}
void EQStream::PacketQueueClear()
+17 -18
View File
@@ -21,7 +21,6 @@
#include "eq_packet_structs.h"
#include "item.h"
#pragma pack(1)
/*
@@ -37,24 +36,24 @@
*/
struct ExtendedProfile_Struct {
// Pet stuff
uint16 pet_id;
uint16 old_pet_hp;
uint16 old_pet_mana;
SpellBuff_Struct pet_buffs[BUFF_COUNT];
uint32 pet_items[_MaterialCount];
char merc_name[64];
uint16 pet_id; /* Not Used */
uint16 old_pet_hp; /* Not Used */
uint16 old_pet_mana; /* Not Used */
SpellBuff_Struct pet_buffs[BUFF_COUNT]; /* Not Used */
uint32 pet_items[_MaterialCount]; /* Not Used */
char merc_name[64]; /* Used */
uint32 aa_effects;
uint32 perAA; //% of exp going to AAs
uint32 expended_aa; // Total of expended AA
uint32 pet_hp;
uint32 pet_mana;
uint32 mercTemplateID;
uint32 mercSuspendedTime;
bool mercIsSuspended;
uint32 mercTimerRemaining;
uint8 mercGender;
int32 mercState;
uint32 aa_effects; /* Used */
uint32 perAA; /* Used: % of exp going to AAs */
uint32 expended_aa; /* Used: Total of expended AA */
uint32 pet_hp; /* Not Used */
uint32 pet_mana; /* Not Used */
uint32 mercTemplateID; /* Not Used */
uint32 mercSuspendedTime; /* Not Used */
bool mercIsSuspended; /* Not Used */
uint32 mercTimerRemaining; /* Not Used */
uint8 mercGender; /* Not Used */
int32 mercState; /* Not Used */
};
#pragma pack()
+4 -4
View File
@@ -756,7 +756,7 @@ bool BaseGuildManager::DBSetGuild(uint32 charid, uint32 guild_id, uint8 rank) {
std::string query;
if(guild_id != GUILD_NONE) {
query = StringFormat("REPLACE INTO guild_members (char_id,guild_id,rank) VALUES(%d,%d,%d)", charid, guild_id, rank);
query = StringFormat("REPLACE INTO guild_members (char_id,guild_id,rank,public_note) VALUES(%d,%d,%d,'')", charid, guild_id, rank);
auto results = m_db->QueryDatabase(query);
if (!results.Success()) {
@@ -897,10 +897,10 @@ bool BaseGuildManager::QueryWithLogging(std::string query, const char *errmsg) {
" FROM vwBotCharacterMobs AS c LEFT JOIN vwGuildMembers AS g ON c.id=g.char_id AND c.mobtype = g.mobtype "
#else
#define GuildMemberBaseQuery \
"SELECT c.id,c.name,c.class,c.level,c.timelaston,c.zoneid," \
"SELECT c.id,c.name,c.class,c.level,c.last_login,c.zone_id," \
" g.guild_id,g.rank,g.tribute_enable,g.total_tribute,g.last_tribute," \
" g.banker,g.public_note,g.alt " \
" FROM character_ AS c LEFT JOIN guild_members AS g ON c.id=g.char_id "
" 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) {
//fields from `characer_`
@@ -1241,7 +1241,7 @@ BaseGuildManager::GuildInfo::GuildInfo() {
uint32 BaseGuildManager::DoesAccountContainAGuildLeader(uint32 AccountID)
{
std::string query = StringFormat("SELECT guild_id FROM guild_members WHERE char_id IN "
"(SELECT id FROM character_ WHERE account_id = %i) AND rank = 2",
"(SELECT id FROM `character_data` WHERE account_id = %i) AND rank = 2",
AccountID);
auto results = m_db->QueryDatabase(query);
if (!results.Success())
+1 -315
View File
@@ -24,318 +24,4 @@
#ifndef WIN32
#include <netinet/in.h> //for htonl
#endif
/*
void Database::GetGuildMembers(uint32 guild_id, GuildMember_Struct* gms){
char errbuf[MYSQL_ERRMSG_SIZE];
char *query = 0;
MYSQL_RES *result;
MYSQL_ROW row;
uint32 count=0;
uint32 length=0;
if (RunQuery(query, MakeAnyLenString(&query, "Select name,profile,timelaston,guildrank,publicnote from character_ where guild=%i", guild_id), errbuf, &result)) {
safe_delete_array(query);
while( ( row = mysql_fetch_row(result) ) ){
strcpy(gms->member[count].name,row[0]);
length+=strlen(row[0])+strlen(row[4]);
PlayerProfile_Struct* pps=(PlayerProfile_Struct*)row[1];
gms->member[count].level=htonl(pps->level);
gms->member[count].zoneid=(pps->zone_id*256);
gms->member[count].timelaston=htonl(atol(row[2]));
gms->member[count].class_=htonl(pps->class_);
gms->member[count].rank=atoi(row[3]);
strcpy(gms->member[count].publicnote,row[4]);
count++;
}
mysql_free_result(result);
}
else {
LogFile->write(EQEMuLog::Error, "Error in GetGuildMembers query '%s': %s", query, errbuf);
safe_delete_array(query);
}
gms->count=count;
gms->length=length;
}
uint32 Database::NumberInGuild(uint32 guild_id) {
char errbuf[MYSQL_ERRMSG_SIZE];
char *query = 0;
MYSQL_RES *result;
MYSQL_ROW row;
if (RunQuery(query, MakeAnyLenString(&query, "Select count(id) from character_ where guild=%i", guild_id), errbuf, &result)) {
safe_delete_array(query);
if (mysql_num_rows(result) == 1) {
row = mysql_fetch_row(result);
uint32 ret = atoi(row[0]);
mysql_free_result(result);
return ret;
}
mysql_free_result(result);
}
else {
LogFile->write(EQEMuLog::Error, "Error in NumberInGuild query '%s': %s", query, errbuf);
safe_delete_array(query);
return 0;
}
return 0;
}
bool Database::SetGuild(char* name, uint32 guild_id, uint8 guildrank) {
char errbuf[MYSQL_ERRMSG_SIZE];
char *query = 0;
uint32 affected_rows = 0;
if (RunQuery(query, MakeAnyLenString(&query, "UPDATE character_ SET guild=%i, guildrank=%i WHERE name='%s'", guild_id, guildrank, name), errbuf, 0, &affected_rows)) {
safe_delete_array(query);
if (affected_rows == 1)
return true;
else
return false;
}
else {
LogFile->write(EQEMuLog::Error, "Error in SetGuild query '%s': %s", query, errbuf);
safe_delete_array(query);
return false;
}
return false;
}
bool Database::SetGuild(uint32 charid, uint32 guild_id, uint8 guildrank) {
char errbuf[MYSQL_ERRMSG_SIZE];
char *query = 0;
uint32 affected_rows = 0;
if (RunQuery(query, MakeAnyLenString(&query, "UPDATE character_ SET guild=%i, guildrank=%i WHERE id=%i", guild_id, guildrank, charid), errbuf, 0, &affected_rows)) {
safe_delete_array(query);
if (affected_rows == 1)
return true;
else
return false;
}
else {
LogFile->write(EQEMuLog::Error, "Error in SetGuild query '%s': %s", query, errbuf);
safe_delete_array(query);
return false;
}
return false;
}
bool Database::DeleteGuild(uint32 guild_id)
{
char errbuf[MYSQL_ERRMSG_SIZE];
char *query = 0;
char *query2 = 0;
uint32 affected_rows = 0;
if (RunQuery(query, MakeAnyLenString(&query, "DELETE FROM guilds WHERE id=%i;", guild_id), errbuf, 0, &affected_rows)) {
safe_delete_array(query);
if (affected_rows == 1) {
if(!RunQuery(query2, MakeAnyLenString(&query2, "update character_ set guild=0,guildrank=0 where guild=%i", guild_id), errbuf, 0, &affected_rows))
LogFile->write(EQEMuLog::Error, "Error in DeleteGuild cleanup query '%s': %s", query2, errbuf);
safe_delete_array(query2);
return true;
}
else
return false;
}
else {
LogFile->write(EQEMuLog::Error, "Error in DeleteGuild query '%s': %s", query, errbuf);
safe_delete_array(query);
return false;
}
return false;
}
bool Database::RenameGuild(uint32 guild_id, const char* name) {
char errbuf[MYSQL_ERRMSG_SIZE];
char *query = 0;
uint32 affected_rows = 0;
char buf[65];
DoEscapeString(buf, name, strlen(name)) ;
if (RunQuery(query, MakeAnyLenString(&query, "Update guilds set name='%s' WHERE id=%i;", buf, guild_id), errbuf, 0, &affected_rows)) {
safe_delete_array(query);
if (affected_rows == 1)
return true;
else
return false;
}
else {
LogFile->write(EQEMuLog::Error, "Error in RenameGuild query '%s': %s", query, errbuf);
safe_delete_array(query);
return false;
}
return false;
}
bool Database::EditGuild(uint32 guild_id, uint8 ranknum, GuildRankLevel_Struct* grl)
{
char errbuf[MYSQL_ERRMSG_SIZE];
char *query = 0;
int chars = 0;
uint32 affected_rows = 0;
char buf[203];
char buf2[8];
DoEscapeString(buf, grl->rankname, strlen(grl->rankname)) ;
buf2[GUILD_HEAR] = grl->heargu + '0';
buf2[GUILD_SPEAK] = grl->speakgu + '0';
buf2[GUILD_INVITE] = grl->invite + '0';
buf2[GUILD_REMOVE] = grl->remove + '0';
buf2[GUILD_PROMOTE] = grl->promote + '0';
buf2[GUILD_DEMOTE] = grl->demote + '0';
buf2[GUILD_MOTD] = grl->motd + '0';
buf2[GUILD_WARPEACE] = grl->warpeace + '0';
if (ranknum == 0)
chars = MakeAnyLenString(&query, "Update guilds set rank%ititle='%s' WHERE id=%i;", ranknum, buf, guild_id);
else
chars = MakeAnyLenString(&query, "Update guilds set rank%ititle='%s', rank%i='%s' WHERE id=%i;", ranknum, buf, ranknum, buf2, guild_id);
if (RunQuery(query, chars, errbuf, 0, &affected_rows)) {
safe_delete_array(query);
if (affected_rows == 1)
return true;
else
return false;
}
else {
LogFile->write(EQEMuLog::Error, "Error in EditGuild query '%s': %s", query, errbuf);
safe_delete_array(query);
return false;
}
return false;
}
bool Database::GetGuildNameByID(uint32 guild_id, char * name) {
if (!name || !guild_id) return false;
char errbuf[MYSQL_ERRMSG_SIZE];
char *query = 0;
MYSQL_RES *result;
MYSQL_ROW row;
if (RunQuery(query, MakeAnyLenString(&query, "select name from guilds where id='%i'", guild_id), errbuf, &result)) {
safe_delete_array(query);
row = mysql_fetch_row(result);
if (row[0])
sprintf(name,"%s",row[0]);
mysql_free_result(result);
return true;
}
else {
LogFile->write(EQEMuLog::Error, "Error in GetGuildNameByID query '%s': %s", query, errbuf);
safe_delete_array(query);
return false;
}
return false;
}
uint32 Database::GetGuildIDbyLeader(uint32 leader)
{
char errbuf[MYSQL_ERRMSG_SIZE];
char *query = 0;
MYSQL_RES *result;
MYSQL_ROW row;
if (RunQuery(query, MakeAnyLenString(&query, "SELECT id FROM guilds WHERE leader=%i", leader), errbuf, &result)) {
safe_delete_array(query);
if (mysql_num_rows(result) == 1)
{
row = mysql_fetch_row(result);
uint32 tmp = atoi(row[0]);
mysql_free_result(result);
return tmp;
}
mysql_free_result(result);
}
else {
LogFile->write(EQEMuLog::Error, "Error in Getguild_idbyLeader query '%s': %s", query, errbuf);
safe_delete_array(query);
}
return 0;
}
bool Database::SetGuildLeader(uint32 guild_id, uint32 leader)
{
char errbuf[MYSQL_ERRMSG_SIZE];
char *query = 0;
uint32 affected_rows = 0;
if (RunQuery(query, MakeAnyLenString(&query, "UPDATE guilds SET leader=%i WHERE id=%i", leader, guild_id), errbuf, 0, &affected_rows)) {
safe_delete_array(query);
if (affected_rows == 1)
return true;
else
return false;
}
else {
LogFile->write(EQEMuLog::Error, "Error in SetGuildLeader query '%s': %s", query, errbuf);
safe_delete_array(query);
return false;
}
return false;
}
bool Database::SetGuildMOTD(uint32 guild_id, const char* motd) {
char errbuf[MYSQL_ERRMSG_SIZE];
char *query = 0;
char* motdbuf = 0;
uint32 affected_rows = 0;
motdbuf = new char[(strlen(motd)*2)+3];
DoEscapeString(motdbuf, motd, strlen(motd)) ;
if (RunQuery(query, MakeAnyLenString(&query, "Update guilds set motd='%s' WHERE id=%i;", motdbuf, guild_id), errbuf, 0, &affected_rows)) {
safe_delete_array(query);
delete motdbuf;
if (affected_rows == 1)
return true;
else
return false;
}
else
{
LogFile->write(EQEMuLog::Error, "Error in SetGuildMOTD query '%s': %s", query, errbuf);
safe_delete_array(query);
delete motdbuf;
return false;
}
return false;
}
string Database::GetGuildMOTD(uint32 guild_id)
{
char errbuf[MYSQL_ERRMSG_SIZE];
char *query = 0;
MYSQL_RES *result;
MYSQL_ROW row;
string motd_str;
if (RunQuery(query, MakeAnyLenString(&query, "SELECT motd FROM guilds WHERE id=%i", guild_id), errbuf, &result)) {
safe_delete_array(query);
if (mysql_num_rows(result) == 1) {
row = mysql_fetch_row(result);
if (row[0])
motd_str = row[0];
}
mysql_free_result(result);
}
else {
LogFile->write(EQEMuLog::Error, "Error in GetGuildMOTD query '%s': %s", query, errbuf);
safe_delete_array(query);
}
return motd_str;
}
*/
#endif
+24
View File
@@ -911,6 +911,30 @@ bool Inventory::CanItemFitInContainer(const Item_Struct *ItemToTry, const Item_S
return true;
}
bool Inventory::SupportsClickCasting(int16 slot_id)
{
// there are a few non-potion items that identify as ItemTypePotion..so, we still need to ubiquitously include the equipment range
if ((uint16)slot_id <= EmuConstants::GENERAL_END || slot_id == MainPowerSource)
{
return true;
}
else if (slot_id >= EmuConstants::GENERAL_BAGS_BEGIN && slot_id <= EmuConstants::GENERAL_BAGS_END)
{
if (EQLimits::AllowsClickCastFromBag(m_version))
return true;
}
return false;
}
bool Inventory::SupportsPotionBeltCasting(int16 slot_id)
{
if ((uint16)slot_id <= EmuConstants::GENERAL_END || slot_id == MainPowerSource || (slot_id >= EmuConstants::GENERAL_BAGS_BEGIN && slot_id <= EmuConstants::GENERAL_BAGS_END))
return true;
return false;
}
// Test whether a given slot can support a container item
bool Inventory::SupportsContainers(int16 slot_id)
{
+25 -2
View File
@@ -121,8 +121,22 @@ public:
// Public Methods
///////////////////////////////
Inventory() { m_version = EQClientUnknown; m_versionset = false; }
~Inventory();
// Inventory v2 creep
bool SetInventoryVersion(EQClientVersion version) {
if (!m_versionset) {
m_version = version;
return (m_versionset = true);
}
else {
return false;
}
}
EQClientVersion GetInventoryVersion() { return m_version; }
static void CleanDirty();
static void MarkDirty(ItemInst *inst);
@@ -132,7 +146,7 @@ public:
inline iter_queue cursor_begin() { return m_cursor.begin(); }
inline iter_queue cursor_end() { return m_cursor.end(); }
inline bool CursorEmpty() { return (m_cursor.size() == 0); }
inline bool CursorEmpty() { return (m_cursor.size() == 0); }
// Retrieve a read-only item from inventory
inline const ItemInst* operator[](int16 slot_id) const { return GetItem(slot_id); }
@@ -183,6 +197,10 @@ public:
static bool CanItemFitInContainer(const Item_Struct *ItemToTry, const Item_Struct *Container);
// Test for valid inventory casting slot
bool SupportsClickCasting(int16 slot_id);
bool SupportsPotionBeltCasting(int16 slot_id);
// Test whether a given slot can support a container item
static bool SupportsContainers(int16 slot_id);
@@ -229,7 +247,12 @@ protected:
std::map<int16, ItemInst*> m_bank; // Items in character bank
std::map<int16, ItemInst*> m_shbank; // Items in character shared bank
std::map<int16, ItemInst*> m_trade; // Items in a trade session
ItemInstQueue m_cursor; // Items on cursor: FIFO
ItemInstQueue m_cursor; // Items on cursor: FIFO
private:
// Active inventory version
EQClientVersion m_version;
bool m_versionset;
};
class SharedDatabase;
+9 -9
View File
@@ -1,13 +1,13 @@
//Mail and Chat Channels
N(OP_MailLogin),
N(OP_Mail),
N(OP_Buddy),
N(OP_ChannelAnnounceJoin),
N(OP_ChannelAnnounceLeave),
N(OP_Buddy),
N(OP_MailHeaderCount),
N(OP_MailHeader),
N(OP_MailSendBody),
N(OP_MailNew),
N(OP_MailDeliveryStatus),
N(OP_MailboxChange),
N(OP_Ignore),
N(OP_Mail),
N(OP_MailboxChange),
N(OP_MailDeliveryStatus),
N(OP_MailHeader),
N(OP_MailHeaderCount),
N(OP_MailLogin),
N(OP_MailNew),
N(OP_MailSendBody),
+23
View File
@@ -387,3 +387,26 @@ float EQHtoFloat(int d)
{
return(360.0f - float((d * 360) >> 11));
}
// returns a swapped-bit value for use in client translator and inventory functions
uint32 SwapBits21and22(uint32 mask)
{
static const uint32 BIT21 = 1 << 21;
static const uint32 BIT22 = 1 << 22;
static const uint32 SWAPBITS = (BIT21 | BIT22);
if ((bool)(mask & BIT21) != (bool)(mask & BIT22))
mask ^= SWAPBITS;
return mask;
}
// returns an unset bit 22 value for use in client translators
uint32 Catch22(uint32 mask)
{
static const uint32 KEEPBITS = ~(1 << 22);
mask &= KEEPBITS;
return mask;
}
+2
View File
@@ -102,6 +102,8 @@ int FloatToEQ13(float d);
int NewFloatToEQ13(float d);
int FloatToEQ19(float d);
int FloatToEQH(float d);
uint32 SwapBits21and22(uint32 mask);
uint32 Catch22(uint32 mask);
// macro to catch fp errors (provided by noudness)
#define FCMP(a,b) (fabs(a-b) < FLT_EPSILON)
+3
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)
@@ -100,6 +101,7 @@ MySQLRequestResult::MySQLRequestResult(MySQLRequestResult&& moveItem)
m_RowsAffected = moveItem.m_RowsAffected;
m_LastInsertedID = moveItem.m_LastInsertedID;
m_ColumnLengths = moveItem.m_ColumnLengths;
m_ColumnCount = moveItem.m_ColumnCount;
m_Fields = moveItem.m_Fields;
// Keeps deconstructor from double freeing
@@ -127,6 +129,7 @@ MySQLRequestResult& MySQLRequestResult::operator=(MySQLRequestResult&& other)
m_CurrentRow = other.m_CurrentRow;
m_OneBeyondRow = other.m_OneBeyondRow;
m_ColumnLengths = other.m_ColumnLengths;
m_ColumnCount = other.m_ColumnCount;
m_Fields = other.m_Fields;
// Keeps deconstructor from double freeing
+1 -1
View File
@@ -305,7 +305,7 @@ OUTz(OP_FinishWindow2);
//OUTv(OP_AdventureInfo, strlen(p)+1);
//OUTv(OP_AdventureMerchantResponse, strlen(msg)+2);
OUTv(OP_ItemPacket, ItemPacket_Struct);
OUTv(OP_BuffFadeMsg, BuffFadeMsg_Struct);
OUTv(OP_ColoredText, ColoredText_Struct);
OUTv(OP_FormattedMessage, FormattedMessage_Struct);
OUTv(OP_GuildMemberList, uint32); //variable length, but nasty
OUTv(OP_InterruptCast, InterruptCast_Struct);
+1 -1
View File
@@ -160,7 +160,7 @@ void load_opcode_names()
opcode_map[0x0192]="LiveOP_YellForHelp";
opcode_map[0x00ef]="LiveOP_SafePoint";
opcode_map[0x0157]="LiveOP_Buff";
opcode_map[0x00c0]="LiveOP_BuffFadeMsg";
opcode_map[0x00c0]="LiveOP_ColoredText";
opcode_map[0x0440]="LiveOP_MultiLineMsg";
opcode_map[0x021c]="LiveOP_SpecialMesg";
opcode_map[0x0013]="LiveOP_Consent";
File diff suppressed because it is too large Load Diff
+2 -1
View File
@@ -22,7 +22,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#ifndef CLIENT62_CONSTANTS_H_
#define CLIENT62_CONSTANTS_H_
#include "../common/types.h"
#include "../types.h"
namespace Client62 {
namespace maps {
@@ -180,6 +180,7 @@ namespace Client62 {
namespace limits {
static const bool ALLOWS_EMPTY_BAG_IN_BAG = false;
static const bool ALLOWS_CLICK_CAST_FROM_BAG = false;
static const bool COIN_HAS_WEIGHT = true;
}
+26 -27
View File
@@ -1,36 +1,35 @@
//list of packets we need to encode on the way out:
// out-going packets that require an ENCODE translation:
E(OP_Action)
E(OP_BazaarSearch)
E(OP_BecomeTrader)
E(OP_CharInventory)
E(OP_DeleteSpawn)
E(OP_GuildMemberLevelUpdate)
E(OP_GuildMemberList)
E(OP_Illusion)
E(OP_ItemLinkResponse)
E(OP_ItemPacket)
E(OP_LeadershipExpUpdate)
E(OP_NewSpawn)
E(OP_OnLevelMessage)
E(OP_PetBuffWindow)
E(OP_PlayerProfile)
E(OP_ReadBook)
E(OP_RespondAA)
E(OP_SendAATable)
E(OP_SendCharInfo)
E(OP_LeadershipExpUpdate)
E(OP_PlayerProfile)
E(OP_NewSpawn)
E(OP_ZoneSpawns)
E(OP_ZoneEntry)
E(OP_ItemPacket)
E(OP_ItemLinkResponse)
E(OP_CharInventory)
E(OP_GuildMemberList)
E(OP_ZoneServerReady)
E(OP_GuildMemberLevelUpdate)
E(OP_ReadBook)
E(OP_Illusion)
E(OP_Track)
E(OP_BazaarSearch)
E(OP_RespondAA)
E(OP_DeleteSpawn)
E(OP_WearChange)
E(OP_Action)
E(OP_BecomeTrader)
E(OP_PetBuffWindow)
E(OP_OnLevelMessage)
//list of packets we need to decode on the way in:
D(OP_SetServerFilter)
E(OP_ZoneEntry)
E(OP_ZoneServerReady)
E(OP_ZoneSpawns)
// incoming packets that require a DECODE translation:
D(OP_CharacterCreate)
D(OP_ItemLinkClick)
D(OP_WhoAllRequest)
D(OP_ReadBook)
D(OP_FaceChange)
D(OP_ItemLinkClick)
D(OP_ReadBook)
D(OP_SetServerFilter)
D(OP_WearChange)
D(OP_WhoAllRequest)
#undef E
#undef D
+1 -1
View File
@@ -2969,7 +2969,7 @@ struct GroupInvite_Struct {
// uint8 unknown128[65];
};
struct BuffFadeMsg_Struct {
struct ColoredText_Struct {
uint32 color;
char msg[1];
};
+4906 -4771
View File
File diff suppressed because it is too large Load Diff
+2 -1
View File
@@ -22,7 +22,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#ifndef RoF_CONSTANTS_H_
#define RoF_CONSTANTS_H_
#include "../common/types.h"
#include "../types.h"
namespace RoF {
namespace maps {
@@ -184,6 +184,7 @@ namespace RoF {
namespace limits {
static const bool ALLOWS_EMPTY_BAG_IN_BAG = true;
static const bool ALLOWS_CLICK_CAST_FROM_BAG = true;
static const bool COIN_HAS_WEIGHT = false;
}
+140 -142
View File
@@ -1,162 +1,160 @@
//list of packets we need to encode on the way out:
E(OP_SendCharInfo)
E(OP_ZoneServerInfo)
E(OP_SendAATable)
E(OP_PlayerProfile)
E(OP_ZoneEntry)
E(OP_CharInventory)
E(OP_NewZone)
E(OP_SpawnDoor)
E(OP_GroundSpawn)
E(OP_SendZonepoints)
E(OP_NewSpawn)
E(OP_ZoneSpawns)
E(OP_ItemLinkResponse)
E(OP_ItemPacket)
E(OP_GuildMemberList)
E(OP_Illusion)
E(OP_ManaChange)
E(OP_ClientUpdate)
E(OP_LeadershipExpUpdate)
E(OP_ExpansionInfo)
E(OP_LogServer)
E(OP_Damage)
E(OP_Buff)
// out-going packets that require an ENCODE translation:
E(OP_Action)
E(OP_Consider)
E(OP_CancelTrade)
E(OP_ShopPlayerSell)
E(OP_DeleteItem)
E(OP_ItemVerifyReply)
E(OP_DeleteCharge)
E(OP_MoveItem)
//E(OP_OpenNewTasksWindow)
E(OP_BazaarSearch)
E(OP_Trader)
E(OP_TraderBuy)
E(OP_LootItem)
E(OP_TributeItem)
E(OP_SomeItemPacketMaybe)
E(OP_ReadBook)
E(OP_Stun)
E(OP_ZonePlayerToBind)
E(OP_AdventureMerchantSell)
E(OP_RaidUpdate)
E(OP_RaidJoin)
E(OP_VetRewardsAvaliable)
E(OP_InspectRequest)
E(OP_GroupInvite)
E(OP_GroupFollow)
E(OP_GroupFollow2)
E(OP_GroupUpdate)
E(OP_GroupCancelInvite)
E(OP_WhoAllResponse)
E(OP_Track)
E(OP_ShopPlayerBuy)
E(OP_PetBuffWindow)
E(OP_OnLevelMessage)
E(OP_Barter)
E(OP_AltCurrency)
E(OP_AltCurrencySell)
E(OP_Animation)
E(OP_ApplyPoison)
E(OP_Barter)
E(OP_BazaarSearch)
E(OP_BeginCast)
E(OP_BlockedBuffs)
E(OP_Buff)
E(OP_BuffCreate)
E(OP_CancelTrade)
E(OP_CastSpell)
E(OP_ChannelMessage)
E(OP_GuildsList)
E(OP_CharInventory)
E(OP_ClickObjectAction)
E(OP_ClientUpdate)
E(OP_Consider)
E(OP_Damage)
E(OP_DeleteCharge)
E(OP_DeleteItem)
E(OP_DeleteSpawn)
E(OP_DisciplineUpdate)
E(OP_DzCompass)
E(OP_DzExpeditionEndsWarning)
E(OP_DzExpeditionInfo)
E(OP_DzCompass)
E(OP_DzMemberList)
E(OP_DzExpeditionList)
E(OP_DzLeaderStatus)
E(OP_DzJoinExpeditionConfirm)
E(OP_TargetBuffs)
E(OP_BuffCreate)
E(OP_SpawnAppearance)
E(OP_RespondAA)
E(OP_DisciplineUpdate)
E(OP_AltCurrencySell)
E(OP_AltCurrency)
E(OP_RequestClientZoneChange)
E(OP_ZoneChange)
E(OP_WearChange)
E(OP_ShopRequest)
E(OP_CastSpell)
E(OP_InterruptCast)
E(OP_SendMembership)
E(OP_Animation)
E(OP_HPUpdate)
E(OP_BlockedBuffs)
E(OP_RemoveBlockedBuffs)
E(OP_DeleteSpawn)
E(OP_ClickObjectAction)
E(OP_RecipeAutoCombine)
E(OP_GMTrainSkillConfirm)
E(OP_SkillUpdate)
E(OP_TributeInfo)
E(OP_TaskHistoryReply)
E(OP_TaskDescription)
E(OP_SetGuildRank)
E(OP_MercenaryDataUpdate)
E(OP_MercenaryDataResponse)
E(OP_GuildMemberUpdate)
E(OP_DzLeaderStatus)
E(OP_DzMemberList)
E(OP_ExpansionInfo)
E(OP_GMLastName)
E(OP_BeginCast)
E(OP_GMTrainSkillConfirm)
E(OP_GroundSpawn)
E(OP_GroupCancelInvite)
E(OP_GroupFollow)
E(OP_GroupFollow2)
E(OP_GroupInvite)
E(OP_GroupUpdate)
E(OP_GuildMemberList)
E(OP_GuildMemberUpdate)
E(OP_GuildsList)
E(OP_HPUpdate)
E(OP_Illusion)
E(OP_InspectRequest)
E(OP_InterruptCast)
E(OP_ItemLinkResponse)
E(OP_ItemPacket)
E(OP_ItemVerifyReply)
E(OP_LeadershipExpUpdate)
E(OP_LogServer)
E(OP_LootItem)
E(OP_ManaChange)
E(OP_MercenaryDataResponse)
E(OP_MercenaryDataUpdate)
E(OP_MoveItem)
E(OP_NewSpawn)
E(OP_NewZone)
E(OP_OnLevelMessage)
//E(OP_OpenNewTasksWindow)
E(OP_PetBuffWindow)
E(OP_PlayerProfile)
E(OP_RaidJoin)
E(OP_RaidUpdate)
E(OP_ReadBook)
E(OP_RecipeAutoCombine)
E(OP_RemoveBlockedBuffs)
E(OP_RequestClientZoneChange)
E(OP_RespondAA)
E(OP_RezzRequest)
//list of packets we need to decode on the way in:
D(OP_SetServerFilter)
D(OP_CharacterCreate)
D(OP_ItemLinkClick)
D(OP_ConsiderCorpse)
D(OP_Consider)
D(OP_ClientUpdate)
D(OP_MoveItem)
D(OP_WhoAllRequest)
E(OP_SendAATable)
E(OP_SendCharInfo)
E(OP_SendMembership)
E(OP_SendZonepoints)
E(OP_SetGuildRank)
E(OP_ShopPlayerBuy)
E(OP_ShopPlayerSell)
E(OP_ShopRequest)
E(OP_SkillUpdate)
E(OP_SomeItemPacketMaybe)
E(OP_SpawnAppearance)
E(OP_SpawnDoor)
E(OP_Stun)
E(OP_TargetBuffs)
E(OP_TaskDescription)
E(OP_TaskHistoryReply)
E(OP_Track)
E(OP_Trader)
E(OP_TraderBuy)
E(OP_TributeInfo)
E(OP_TributeItem)
E(OP_VetRewardsAvaliable)
E(OP_WearChange)
E(OP_WhoAllResponse)
E(OP_ZoneChange)
E(OP_ZoneEntry)
E(OP_ZonePlayerToBind)
E(OP_ZoneServerInfo)
E(OP_ZoneSpawns)
// incoming packets that require a DECODE translation:
D(OP_AdventureMerchantSell)
D(OP_AltCurrencySell)
D(OP_AltCurrencySellSelection)
D(OP_ApplyPoison)
D(OP_AugmentInfo)
D(OP_AugmentItem)
D(OP_BazaarSearch)
D(OP_BlockedBuffs)
D(OP_Buff)
D(OP_ShopPlayerSell)
D(OP_Consume)
D(OP_BuffRemoveRequest)
D(OP_CastSpell)
D(OP_Save)
D(OP_ItemVerifyRequest)
D(OP_GroupInvite)
D(OP_GroupInvite2)
D(OP_ChannelMessage)
D(OP_CharacterCreate)
D(OP_ClientUpdate)
D(OP_Consider)
D(OP_ConsiderCorpse)
D(OP_Consume)
D(OP_Damage)
D(OP_DeleteItem)
D(OP_EnvDamage)
D(OP_FaceChange)
D(OP_FindPersonRequest)
D(OP_GMLastName)
D(OP_GroupCancelInvite)
D(OP_GroupDisband)
D(OP_GroupFollow)
D(OP_GroupFollow2)
D(OP_GroupDisband)
D(OP_GroupCancelInvite)
D(OP_FindPersonRequest)
D(OP_TraderBuy)
D(OP_LootItem)
D(OP_TributeItem)
D(OP_ReadBook)
D(OP_AugmentInfo)
D(OP_FaceChange)
D(OP_AdventureMerchantSell)
D(OP_TradeSkillCombine)
D(OP_RaidInvite)
D(OP_InspectRequest)
D(OP_ShopPlayerBuy)
D(OP_BazaarSearch)
D(OP_LoadSpellSet)
D(OP_ApplyPoison)
D(OP_Damage)
D(OP_EnvDamage)
D(OP_ChannelMessage)
D(OP_DeleteItem)
D(OP_AugmentItem)
D(OP_PetCommands)
D(OP_BuffRemoveRequest)
D(OP_AltCurrencySellSelection)
D(OP_AltCurrencySell)
D(OP_ZoneChange)
D(OP_ZoneEntry)
D(OP_ShopRequest)
D(OP_BlockedBuffs)
D(OP_RemoveBlockedBuffs)
D(OP_RecipeAutoCombine)
D(OP_GroupInvite)
D(OP_GroupInvite2)
D(OP_GuildDemote)
D(OP_GuildRemove)
D(OP_GuildStatus)
D(OP_Trader)
D(OP_GMLastName)
D(OP_InspectRequest)
D(OP_ItemLinkClick)
D(OP_ItemVerifyRequest)
D(OP_LoadSpellSet)
D(OP_LootItem)
D(OP_MoveItem)
D(OP_PetCommands)
D(OP_RaidInvite)
D(OP_ReadBook)
D(OP_RecipeAutoCombine)
D(OP_RemoveBlockedBuffs)
D(OP_RezzAnswer)
D(OP_Save)
D(OP_SetServerFilter)
D(OP_ShopPlayerBuy)
D(OP_ShopPlayerSell)
D(OP_ShopRequest)
D(OP_Trader)
D(OP_TraderBuy)
D(OP_TradeSkillCombine)
D(OP_TributeItem)
D(OP_WhoAllRequest)
D(OP_ZoneChange)
D(OP_ZoneEntry)
#undef E
#undef D
+1 -1
View File
@@ -4106,7 +4106,7 @@ struct GMToggle_Struct {
uint32 toggle;
};
struct BuffFadeMsg_Struct {
struct ColoredText_Struct {
uint32 color;
char msg[1]; //was 1
/*0???*/ uint8 paddingXXX[3]; // always 0's
+3225 -3160
View File
File diff suppressed because it is too large Load Diff
+2 -1
View File
@@ -22,7 +22,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#ifndef SoD_CONSTANTS_H_
#define SoD_CONSTANTS_H_
#include "../common/types.h"
#include "../types.h"
namespace SoD {
namespace maps {
@@ -181,6 +181,7 @@ namespace SoD {
namespace limits {
static const bool ALLOWS_EMPTY_BAG_IN_BAG = false;
static const bool ALLOWS_CLICK_CAST_FROM_BAG = false;
static const bool COIN_HAS_WEIGHT = false;
}
+98 -100
View File
@@ -1,117 +1,115 @@
//list of packets we need to encode on the way out:
E(OP_SendCharInfo)
E(OP_ZoneServerInfo)
E(OP_SendAATable)
E(OP_PlayerProfile)
E(OP_ZoneEntry)
E(OP_CharInventory)
E(OP_NewZone)
E(OP_SpawnDoor)
E(OP_GroundSpawn)
E(OP_SendZonepoints)
E(OP_NewSpawn)
E(OP_ZoneSpawns)
E(OP_ItemLinkResponse)
E(OP_ItemPacket)
E(OP_GuildMemberList)
E(OP_Illusion)
E(OP_ManaChange)
E(OP_ClientUpdate)
E(OP_LeadershipExpUpdate)
E(OP_ExpansionInfo)
E(OP_LogServer)
E(OP_Damage)
E(OP_Buff)
// out-going packets that require an ENCODE translation:
E(OP_Action)
E(OP_Consider)
E(OP_CancelTrade)
E(OP_ShopPlayerSell)
E(OP_DeleteItem)
E(OP_ItemVerifyReply)
E(OP_DeleteCharge)
E(OP_MoveItem)
E(OP_OpenNewTasksWindow)
E(OP_BazaarSearch)
E(OP_Trader)
E(OP_TraderBuy)
E(OP_LootItem)
E(OP_TributeItem)
E(OP_SomeItemPacketMaybe)
E(OP_ReadBook)
E(OP_Stun)
E(OP_ZonePlayerToBind)
E(OP_AdventureMerchantSell)
E(OP_RaidUpdate)
E(OP_RaidJoin)
E(OP_VetRewardsAvaliable)
E(OP_InspectRequest)
E(OP_GroupInvite)
E(OP_GroupFollow)
E(OP_GroupFollow2)
E(OP_GroupUpdate)
E(OP_GroupCancelInvite)
E(OP_WhoAllResponse)
E(OP_Track)
E(OP_ShopPlayerBuy)
E(OP_PetBuffWindow)
E(OP_OnLevelMessage)
E(OP_Barter)
E(OP_AltCurrencySell)
E(OP_ApplyPoison)
E(OP_Barter)
E(OP_BazaarSearch)
E(OP_Buff)
E(OP_CancelTrade)
E(OP_CharInventory)
E(OP_ClientUpdate)
E(OP_Consider)
E(OP_Damage)
E(OP_DeleteCharge)
E(OP_DeleteItem)
E(OP_DzCompass)
E(OP_DzExpeditionEndsWarning)
E(OP_DzExpeditionInfo)
E(OP_DzCompass)
E(OP_DzMemberList)
E(OP_DzExpeditionList)
E(OP_DzLeaderStatus)
E(OP_DzJoinExpeditionConfirm)
E(OP_TargetBuffs)
E(OP_AltCurrencySell)
E(OP_WearChange)
E(OP_DzLeaderStatus)
E(OP_DzMemberList)
E(OP_ExpansionInfo)
E(OP_GroundSpawn)
E(OP_GroupCancelInvite)
E(OP_GroupFollow)
E(OP_GroupFollow2)
E(OP_GroupInvite)
E(OP_GroupUpdate)
E(OP_GuildMemberList)
E(OP_Illusion)
E(OP_InspectRequest)
E(OP_ItemLinkResponse)
E(OP_ItemPacket)
E(OP_ItemVerifyReply)
E(OP_LeadershipExpUpdate)
E(OP_LogServer)
E(OP_LootItem)
E(OP_ManaChange)
E(OP_MercenaryDataResponse)
E(OP_MercenaryDataUpdate)
//list of packets we need to decode on the way in:
D(OP_SetServerFilter)
D(OP_CharacterCreate)
D(OP_ItemLinkClick)
D(OP_ConsiderCorpse)
D(OP_Consider)
D(OP_ClientUpdate)
D(OP_MoveItem)
D(OP_WhoAllRequest)
E(OP_MoveItem)
E(OP_NewSpawn)
E(OP_NewZone)
E(OP_OnLevelMessage)
E(OP_OpenNewTasksWindow)
E(OP_PetBuffWindow)
E(OP_PlayerProfile)
E(OP_RaidJoin)
E(OP_RaidUpdate)
E(OP_ReadBook)
E(OP_SendAATable)
E(OP_SendCharInfo)
E(OP_SendZonepoints)
E(OP_ShopPlayerBuy)
E(OP_ShopPlayerSell)
E(OP_SomeItemPacketMaybe)
E(OP_SpawnDoor)
E(OP_Stun)
E(OP_TargetBuffs)
E(OP_Track)
E(OP_Trader)
E(OP_TraderBuy)
E(OP_TributeItem)
E(OP_VetRewardsAvaliable)
E(OP_WearChange)
E(OP_WhoAllResponse)
E(OP_ZoneEntry)
E(OP_ZonePlayerToBind)
E(OP_ZoneServerInfo)
E(OP_ZoneSpawns)
// incoming packets that require a DECODE translation:
D(OP_AdventureMerchantSell)
D(OP_AltCurrencySell)
D(OP_AltCurrencySellSelection)
D(OP_ApplyPoison)
D(OP_AugmentInfo)
D(OP_AugmentItem)
D(OP_BazaarSearch)
D(OP_Buff)
D(OP_ShopPlayerSell)
D(OP_Consume)
D(OP_Bug)
D(OP_CastSpell)
D(OP_Save)
D(OP_ItemVerifyRequest)
D(OP_GroupInvite)
D(OP_GroupInvite2)
D(OP_CharacterCreate)
D(OP_ClientUpdate)
D(OP_Consider)
D(OP_ConsiderCorpse)
D(OP_Consume)
D(OP_DeleteItem)
D(OP_FaceChange)
D(OP_FindPersonRequest)
D(OP_GroupCancelInvite)
D(OP_GroupDisband)
D(OP_GroupFollow)
D(OP_GroupFollow2)
D(OP_GroupDisband)
D(OP_GroupCancelInvite)
D(OP_FindPersonRequest)
D(OP_TraderBuy)
D(OP_LootItem)
D(OP_TributeItem)
D(OP_ReadBook)
D(OP_AugmentInfo)
D(OP_FaceChange)
D(OP_AdventureMerchantSell)
D(OP_TradeSkillCombine)
D(OP_RaidInvite)
D(OP_GroupInvite)
D(OP_GroupInvite2)
D(OP_InspectRequest)
D(OP_WearChange)
D(OP_ShopPlayerBuy)
D(OP_BazaarSearch)
D(OP_ItemLinkClick)
D(OP_ItemVerifyRequest)
D(OP_LoadSpellSet)
D(OP_ApplyPoison)
D(OP_DeleteItem)
D(OP_AugmentItem)
D(OP_Bug)
D(OP_AltCurrencySellSelection)
D(OP_AltCurrencySell)
D(OP_LootItem)
D(OP_MoveItem)
D(OP_RaidInvite)
D(OP_ReadBook)
D(OP_Save)
D(OP_SetServerFilter)
D(OP_ShopPlayerBuy)
D(OP_ShopPlayerSell)
D(OP_TraderBuy)
D(OP_TradeSkillCombine)
D(OP_TributeItem)
D(OP_WearChange)
D(OP_WhoAllRequest)
#undef E
#undef D
+1 -1
View File
@@ -3693,7 +3693,7 @@ struct GMToggle_Struct {
uint32 toggle;
};
struct BuffFadeMsg_Struct {
struct ColoredText_Struct {
uint32 color;
char msg[1]; //was 1
/*0???*/ uint8 paddingXXX[3]; // always 0's
+2834 -2752
View File
File diff suppressed because it is too large Load Diff
+2 -1
View File
@@ -22,7 +22,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#ifndef SoF_CONSTANTS_H_
#define SoF_CONSTANTS_H_
#include "../common/types.h"
#include "../types.h"
namespace SoF {
namespace maps {
@@ -181,6 +181,7 @@ namespace SoF {
namespace limits {
static const bool ALLOWS_EMPTY_BAG_IN_BAG = false;
static const bool ALLOWS_CLICK_CAST_FROM_BAG = false;
static const bool COIN_HAS_WEIGHT = true;
}
+1 -1
View File
@@ -187,7 +187,7 @@
0x1ee9,
0x7f5d, OP_CastSpell
0x0659, OP_ManaChange
0x3bc7, OP_BuffFadeMsg
0x3bc7, OP_ColoredText
0x3209,
0x6a93, OP_MemorizeSpell
0x1237,
+81 -83
View File
@@ -1,100 +1,98 @@
//list of packets we need to encode on the way out:
E(OP_SendCharInfo)
E(OP_ZoneServerInfo)
E(OP_SendAATable)
E(OP_PlayerProfile)
E(OP_ZoneEntry)
E(OP_CharInventory)
E(OP_NewZone)
E(OP_SpawnDoor)
E(OP_GroundSpawn)
E(OP_SendZonepoints)
E(OP_NewSpawn)
E(OP_ZoneSpawns)
E(OP_ItemLinkResponse)
E(OP_ItemPacket)
E(OP_GuildMemberList)
E(OP_Illusion)
E(OP_ManaChange)
E(OP_ClientUpdate)
E(OP_LeadershipExpUpdate)
E(OP_ExpansionInfo)
E(OP_LogServer)
E(OP_Damage)
E(OP_Buff)
// out-going packets that require an ENCODE translation:
E(OP_Action)
E(OP_Consider)
E(OP_CancelTrade)
E(OP_ShopPlayerSell)
E(OP_DeleteItem)
E(OP_ItemVerifyReply)
E(OP_DeleteCharge)
E(OP_MoveItem)
E(OP_OpenNewTasksWindow)
E(OP_BazaarSearch)
E(OP_Trader)
E(OP_TraderBuy)
E(OP_LootItem)
E(OP_TributeItem)
E(OP_SomeItemPacketMaybe)
E(OP_ReadBook)
E(OP_Stun)
E(OP_ZonePlayerToBind)
E(OP_AdventureMerchantSell)
E(OP_RaidUpdate)
E(OP_RaidJoin)
E(OP_VetRewardsAvaliable)
E(OP_InspectRequest)
E(OP_Track)
E(OP_DeleteSpawn)
E(OP_AltCurrencySell)
E(OP_ApplyPoison)
E(OP_BazaarSearch)
E(OP_BecomeTrader)
E(OP_Buff)
E(OP_CancelTrade)
E(OP_CharInventory)
E(OP_ClientUpdate)
E(OP_Consider)
E(OP_Damage)
E(OP_DeleteCharge)
E(OP_DeleteItem)
E(OP_DeleteSpawn)
E(OP_DzCompass)
E(OP_DzExpeditionEndsWarning)
E(OP_DzExpeditionInfo)
E(OP_DzCompass)
E(OP_DzMemberList)
E(OP_DzExpeditionList)
E(OP_DzLeaderStatus)
E(OP_DzJoinExpeditionConfirm)
E(OP_BecomeTrader)
E(OP_PetBuffWindow)
E(OP_DzLeaderStatus)
E(OP_DzMemberList)
E(OP_ExpansionInfo)
E(OP_GroundSpawn)
E(OP_GuildMemberList)
E(OP_Illusion)
E(OP_InspectRequest)
E(OP_ItemLinkResponse)
E(OP_ItemPacket)
E(OP_ItemVerifyReply)
E(OP_LeadershipExpUpdate)
E(OP_LogServer)
E(OP_LootItem)
E(OP_ManaChange)
E(OP_MoveItem)
E(OP_NewSpawn)
E(OP_NewZone)
E(OP_OnLevelMessage)
E(OP_AltCurrencySell)
E(OP_OpenNewTasksWindow)
E(OP_PetBuffWindow)
E(OP_PlayerProfile)
E(OP_RaidJoin)
E(OP_RaidUpdate)
E(OP_ReadBook)
E(OP_SendAATable)
E(OP_SendCharInfo)
E(OP_SendZonepoints)
E(OP_ShopPlayerSell)
E(OP_SomeItemPacketMaybe)
E(OP_SpawnDoor)
E(OP_Stun)
E(OP_Track)
E(OP_Trader)
E(OP_TraderBuy)
E(OP_TributeItem)
E(OP_VetRewardsAvaliable)
E(OP_WearChange)
//list of packets we need to decode on the way in:
D(OP_SetServerFilter)
D(OP_CharacterCreate)
D(OP_ItemLinkClick)
D(OP_ConsiderCorpse)
D(OP_Consider)
D(OP_ClientUpdate)
D(OP_MoveItem)
D(OP_WhoAllRequest)
E(OP_ZoneEntry)
E(OP_ZonePlayerToBind)
E(OP_ZoneServerInfo)
E(OP_ZoneSpawns)
// incoming packets that require a DECODE translation:
D(OP_AdventureMerchantSell)
D(OP_AltCurrencySell)
D(OP_AltCurrencySellSelection)
D(OP_ApplyPoison)
D(OP_AugmentInfo)
D(OP_AugmentItem)
D(OP_Buff)
D(OP_ShopPlayerSell)
D(OP_Consume)
D(OP_CastSpell)
D(OP_Save)
D(OP_ItemVerifyRequest)
D(OP_CharacterCreate)
D(OP_ClientUpdate)
D(OP_Consider)
D(OP_ConsiderCorpse)
D(OP_Consume)
D(OP_DeleteItem)
D(OP_FaceChange)
D(OP_FindPersonRequest)
D(OP_GroupFollow)
D(OP_GroupFollow2)
D(OP_FindPersonRequest)
D(OP_TraderBuy)
D(OP_LootItem)
D(OP_TributeItem)
D(OP_ReadBook)
D(OP_AugmentInfo)
D(OP_FaceChange)
D(OP_AdventureMerchantSell)
D(OP_TradeSkillCombine)
D(OP_RaidInvite)
D(OP_InspectRequest)
D(OP_ItemLinkClick)
D(OP_ItemVerifyRequest)
D(OP_LootItem)
D(OP_MoveItem)
D(OP_RaidInvite)
D(OP_ReadBook)
D(OP_Save)
D(OP_SetServerFilter)
D(OP_ShopPlayerSell)
D(OP_TraderBuy)
D(OP_TradeSkillCombine)
D(OP_TributeItem)
D(OP_WearChange)
D(OP_ApplyPoison)
D(OP_DeleteItem)
D(OP_AugmentItem)
D(OP_AltCurrencySellSelection)
D(OP_AltCurrencySell)
D(OP_WhoAllRequest)
#undef E
#undef D
+1 -1
View File
@@ -3556,7 +3556,7 @@ struct GMToggle_Struct {
uint32 toggle;
};
struct BuffFadeMsg_Struct {
struct ColoredText_Struct {
uint32 color;
char msg[1]; //was 1
/*0???*/ uint8 paddingXXX[3]; // always 0's
+1419 -1396
View File
File diff suppressed because it is too large Load Diff
+2 -1
View File
@@ -22,7 +22,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#ifndef Titanium_CONSTANTS_H_
#define Titanium_CONSTANTS_H_
#include "../common/types.h"
#include "../types.h"
namespace Titanium {
namespace maps {
@@ -180,6 +180,7 @@ namespace Titanium {
namespace limits {
static const bool ALLOWS_EMPTY_BAG_IN_BAG = false;
static const bool ALLOWS_CLICK_CAST_FROM_BAG = false;
static const bool COIN_HAS_WEIGHT = true;
}
+39 -40
View File
@@ -1,53 +1,52 @@
//list of packets we need to encode on the way out:
E(OP_SendCharInfo)
E(OP_SendAATable)
E(OP_LeadershipExpUpdate)
E(OP_PlayerProfile)
E(OP_NewSpawn)
E(OP_ZoneSpawns)
E(OP_ZoneEntry)
E(OP_CharInventory)
E(OP_ItemLinkResponse)
E(OP_ItemPacket)
// out-going packets that require an ENCODE translation:
E(OP_Action)
E(OP_BazaarSearch)
E(OP_GuildMemberList)
E(OP_ZoneServerReady)
E(OP_GuildMemberLevelUpdate)
E(OP_Trader)
E(OP_TraderBuy)
E(OP_ReadBook)
E(OP_Illusion)
E(OP_VetRewardsAvaliable)
E(OP_InspectRequest)
E(OP_InspectAnswer)
E(OP_Track)
E(OP_RespondAA)
E(OP_BecomeTrader)
E(OP_CharInventory)
E(OP_DeleteSpawn)
E(OP_WearChange)
E(OP_DzCompass)
E(OP_DzExpeditionEndsWarning)
E(OP_DzExpeditionInfo)
E(OP_DzCompass)
E(OP_DzMemberList)
E(OP_DzExpeditionList)
E(OP_DzLeaderStatus)
E(OP_DzJoinExpeditionConfirm)
E(OP_Action)
E(OP_BecomeTrader)
E(OP_PetBuffWindow)
E(OP_OnLevelMessage)
E(OP_DzLeaderStatus)
E(OP_DzMemberList)
E(OP_GuildMemberLevelUpdate)
E(OP_GuildMemberList)
E(OP_Illusion)
E(OP_InspectAnswer)
E(OP_InspectRequest)
E(OP_ItemLinkResponse)
E(OP_ItemPacket)
E(OP_LeadershipExpUpdate)
E(OP_LFGuild)
//list of packets we need to decode on the way in:
D(OP_SetServerFilter)
E(OP_OnLevelMessage)
E(OP_PetBuffWindow)
E(OP_PlayerProfile)
E(OP_NewSpawn)
E(OP_ReadBook)
E(OP_RespondAA)
E(OP_SendCharInfo)
E(OP_SendAATable)
E(OP_Track)
E(OP_Trader)
E(OP_TraderBuy)
E(OP_VetRewardsAvaliable)
E(OP_WearChange)
E(OP_ZoneEntry)
E(OP_ZoneServerReady)
E(OP_ZoneSpawns)
// incoming packets that require a DECODE translation:
D(OP_CharacterCreate)
D(OP_ItemLinkClick)
D(OP_TraderBuy)
D(OP_WhoAllRequest)
D(OP_ReadBook)
D(OP_FaceChange)
D(OP_InspectRequest)
D(OP_InspectAnswer)
D(OP_WearChange)
D(OP_InspectRequest)
D(OP_ItemLinkClick)
D(OP_LFGuild)
D(OP_ReadBook)
D(OP_SetServerFilter)
D(OP_TraderBuy)
D(OP_WearChange)
D(OP_WhoAllRequest)
#undef E
#undef D
+1 -1
View File
@@ -3046,7 +3046,7 @@ struct GroupInvite_Struct {
// uint8 unknown128[65];
};
struct BuffFadeMsg_Struct {
struct ColoredText_Struct {
uint32 color;
char msg[1];
};
+3543 -3470
View File
File diff suppressed because it is too large Load Diff
+2 -1
View File
@@ -22,7 +22,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#ifndef Underfoot_CONSTANTS_H_
#define Underfoot_CONSTANTS_H_
#include "../common/types.h"
#include "../types.h"
namespace Underfoot {
namespace maps {
@@ -181,6 +181,7 @@ namespace Underfoot {
namespace limits {
static const bool ALLOWS_EMPTY_BAG_IN_BAG = false;
static const bool ALLOWS_CLICK_CAST_FROM_BAG = false;
static const bool COIN_HAS_WEIGHT = false;
}
+107 -109
View File
@@ -1,128 +1,126 @@
//list of packets we need to encode on the way out:
E(OP_SendCharInfo)
E(OP_ZoneServerInfo)
E(OP_SendAATable)
E(OP_PlayerProfile)
E(OP_ZoneEntry)
E(OP_CharInventory)
E(OP_NewZone)
E(OP_SpawnDoor)
E(OP_GroundSpawn)
E(OP_SendZonepoints)
E(OP_NewSpawn)
E(OP_ZoneSpawns)
E(OP_ItemLinkResponse)
E(OP_ItemPacket)
E(OP_GuildMemberList)
E(OP_Illusion)
E(OP_ManaChange)
E(OP_ClientUpdate)
E(OP_LeadershipExpUpdate)
E(OP_ExpansionInfo)
E(OP_LogServer)
E(OP_Damage)
E(OP_Buff)
// out-going packets that require an ENCODE translation:
E(OP_Action)
E(OP_Consider)
E(OP_CancelTrade)
E(OP_ShopPlayerSell)
E(OP_DeleteItem)
E(OP_ItemVerifyReply)
E(OP_DeleteCharge)
E(OP_MoveItem)
E(OP_OpenNewTasksWindow)
E(OP_BazaarSearch)
E(OP_Trader)
E(OP_TraderBuy)
E(OP_LootItem)
E(OP_TributeItem)
E(OP_SomeItemPacketMaybe)
E(OP_ReadBook)
E(OP_Stun)
E(OP_ZonePlayerToBind)
E(OP_AdventureMerchantSell)
E(OP_RaidUpdate)
E(OP_RaidJoin)
E(OP_VetRewardsAvaliable)
E(OP_InspectRequest)
E(OP_GroupInvite)
E(OP_GroupFollow)
E(OP_GroupFollow2)
E(OP_GroupUpdate)
E(OP_GroupCancelInvite)
E(OP_WhoAllResponse)
E(OP_Track)
E(OP_ShopPlayerBuy)
E(OP_PetBuffWindow)
E(OP_OnLevelMessage)
E(OP_Barter)
E(OP_AltCurrency)
E(OP_AltCurrencySell)
E(OP_ApplyPoison)
E(OP_Barter)
E(OP_BazaarSearch)
E(OP_Buff)
E(OP_BuffCreate)
E(OP_CancelTrade)
E(OP_ChannelMessage)
E(OP_GuildsList)
E(OP_CharInventory)
E(OP_ClientUpdate)
E(OP_Consider)
E(OP_Damage)
E(OP_DeleteCharge)
E(OP_DeleteItem)
E(OP_DisciplineUpdate)
E(OP_DzCompass)
E(OP_DzExpeditionEndsWarning)
E(OP_DzExpeditionInfo)
E(OP_DzCompass)
E(OP_DzMemberList)
E(OP_DzExpeditionList)
E(OP_DzLeaderStatus)
E(OP_DzJoinExpeditionConfirm)
E(OP_TargetBuffs)
E(OP_BuffCreate)
E(OP_SpawnAppearance)
E(OP_RespondAA)
E(OP_DisciplineUpdate)
E(OP_AltCurrencySell)
E(OP_AltCurrency)
E(OP_WearChange)
E(OP_DzLeaderStatus)
E(OP_DzMemberList)
E(OP_ExpansionInfo)
E(OP_GroundSpawn)
E(OP_GroupCancelInvite)
E(OP_GroupFollow)
E(OP_GroupFollow2)
E(OP_GroupInvite)
E(OP_GroupUpdate)
E(OP_GuildMemberList)
E(OP_GuildsList)
E(OP_Illusion)
E(OP_InspectRequest)
E(OP_ItemLinkResponse)
E(OP_ItemPacket)
E(OP_ItemVerifyReply)
E(OP_LeadershipExpUpdate)
E(OP_LogServer)
E(OP_LootItem)
E(OP_ManaChange)
E(OP_MercenaryDataResponse)
E(OP_MercenaryDataUpdate)
//list of packets we need to decode on the way in:
D(OP_SetServerFilter)
D(OP_CharacterCreate)
D(OP_ItemLinkClick)
D(OP_ConsiderCorpse)
D(OP_Consider)
D(OP_ClientUpdate)
D(OP_MoveItem)
D(OP_WhoAllRequest)
E(OP_MoveItem)
E(OP_NewSpawn)
E(OP_NewZone)
E(OP_OnLevelMessage)
E(OP_OpenNewTasksWindow)
E(OP_PetBuffWindow)
E(OP_PlayerProfile)
E(OP_RaidJoin)
E(OP_RaidUpdate)
E(OP_ReadBook)
E(OP_RespondAA)
E(OP_SendAATable)
E(OP_SendCharInfo)
E(OP_SendZonepoints)
E(OP_ShopPlayerBuy)
E(OP_ShopPlayerSell)
E(OP_SomeItemPacketMaybe)
E(OP_SpawnAppearance)
E(OP_SpawnDoor)
E(OP_Stun)
E(OP_TargetBuffs)
E(OP_Track)
E(OP_Trader)
E(OP_TraderBuy)
E(OP_TributeItem)
E(OP_VetRewardsAvaliable)
E(OP_WearChange)
E(OP_WhoAllResponse)
E(OP_ZoneEntry)
E(OP_ZonePlayerToBind)
E(OP_ZoneServerInfo)
E(OP_ZoneSpawns)
// incoming packets that require a DECODE translation:
D(OP_AdventureMerchantSell)
D(OP_AltCurrencySell)
D(OP_AltCurrencySellSelection)
D(OP_ApplyPoison)
D(OP_AugmentInfo)
D(OP_AugmentItem)
D(OP_BazaarSearch)
D(OP_Buff)
D(OP_ShopPlayerSell)
D(OP_Consume)
D(OP_BuffRemoveRequest)
D(OP_CastSpell)
D(OP_Save)
D(OP_ItemVerifyRequest)
D(OP_GroupInvite)
D(OP_GroupInvite2)
D(OP_ChannelMessage)
D(OP_CharacterCreate)
D(OP_ClientUpdate)
D(OP_Consider)
D(OP_ConsiderCorpse)
D(OP_Consume)
D(OP_Damage)
D(OP_DeleteItem)
D(OP_EnvDamage)
D(OP_FaceChange)
D(OP_FindPersonRequest)
D(OP_GroupCancelInvite)
D(OP_GroupDisband)
D(OP_GroupFollow)
D(OP_GroupFollow2)
D(OP_GroupDisband)
D(OP_GroupCancelInvite)
D(OP_FindPersonRequest)
D(OP_TraderBuy)
D(OP_LootItem)
D(OP_TributeItem)
D(OP_ReadBook)
D(OP_AugmentInfo)
D(OP_FaceChange)
D(OP_AdventureMerchantSell)
D(OP_TradeSkillCombine)
D(OP_RaidInvite)
D(OP_GroupInvite)
D(OP_GroupInvite2)
D(OP_InspectRequest)
D(OP_WearChange)
D(OP_ShopPlayerBuy)
D(OP_BazaarSearch)
D(OP_ItemLinkClick)
D(OP_ItemVerifyRequest)
D(OP_LoadSpellSet)
D(OP_ApplyPoison)
D(OP_Damage)
D(OP_EnvDamage)
D(OP_ChannelMessage)
D(OP_DeleteItem)
D(OP_AugmentItem)
D(OP_LootItem)
D(OP_MoveItem)
D(OP_PetCommands)
D(OP_BuffRemoveRequest)
D(OP_AltCurrencySellSelection)
D(OP_AltCurrencySell)
D(OP_RaidInvite)
D(OP_ReadBook)
D(OP_Save)
D(OP_SetServerFilter)
D(OP_ShopPlayerBuy)
D(OP_ShopPlayerSell)
D(OP_TraderBuy)
D(OP_TradeSkillCombine)
D(OP_TributeItem)
D(OP_WearChange)
D(OP_WhoAllRequest)
#undef E
#undef D
+2 -3
View File
@@ -766,7 +766,7 @@ struct BindStruct {
** OpCode: 0x006a
*/
static const uint32 MAX_PP_LANGUAGE = 25; //
static const uint32 MAX_PP_SPELLBOOK = 480; // Confirmed 60 pages on Underfoot now
static const uint32 MAX_PP_SPELLBOOK = 720; // Confirmed 60 pages on Underfoot now
static const uint32 MAX_PP_MEMSPELL = 10; //was 9 now 10 on Underfoot
static const uint32 MAX_PP_SKILL = _SkillPacketArraySize; // 100 - actual skills buffer size
static const uint32 MAX_PP_AA_ARRAY = 300; //was 299
@@ -879,7 +879,6 @@ struct PlayerProfile_Struct
/*04216*/ uint8 face; // Player face - Actually uint32?
/*04217*/ uint8 unknown04217[147]; // was [175]
/*04364*/ uint32 spell_book[MAX_PP_SPELLBOOK]; // List of the Spells in spellbook 720 = 90 pages [2880] was [1920]
/*06284*/ uint8 unknown06284[960]; // Spacer for the end of the book for now (pages 60 to 90)
/*07244*/ uint32 mem_spells[MAX_PP_MEMSPELL]; // List of spells memorized
/*07284*/ uint8 unknown07284[28]; //#### uint8 unknown04396[32]; in Titanium ####[28]
/*07312*/ uint32 platinum; // Platinum Pieces on player
@@ -3736,7 +3735,7 @@ struct GMToggle_Struct {
uint32 toggle;
};
struct BuffFadeMsg_Struct {
struct ColoredText_Struct {
uint32 color;
char msg[1]; //was 1
/*0???*/ uint8 paddingXXX[3]; // always 0's
+2
View File
@@ -321,6 +321,8 @@ RULE_INT ( Spells, AI_PursueDetrimentalChance, 90) // Chance while chasing targe
RULE_INT ( Spells, AI_IdleNoSpellMinRecast, 500) // AI spell recast time(MS) check when no spell is cast while idle. (min time in random)
RULE_INT ( Spells, AI_IdleNoSpellMaxRecast, 2000) // AI spell recast time(MS) check when no spell is cast while chasing target. (max time in random)
RULE_INT ( Spells, AI_IdleBeneficialChance, 100) // Chance while idle to do a beneficial spell on self or others.
RULE_BOOL ( Spells, SHDProcIDOffByOne, true) // pre June 2009 SHD spell procs were off by 1, they stopped doing this in June 2009 (so UF+ spell files need this false)
RULE_BOOL ( Spells, Jun182014HundredHandsRevamp, false) // this should be true for if you import a spell file newer than June 18, 2014
RULE_CATEGORY_END()
+19 -6
View File
@@ -180,13 +180,15 @@
#define ServerOP_CZMessagePlayer 0x4008
#define ServerOP_ReloadWorld 0x4009
#define ServerOP_QSPlayerLogTrades 0x4010
#define ServerOP_QSPlayerLogHandins 0x4011
#define ServerOP_QSPlayerLogNPCKills 0x4012
#define ServerOP_QSPlayerLogDeletes 0x4013
#define ServerOP_QSPlayerLogMoves 0x4014
#define ServerOP_QSPlayerLogTrades 0x4010
#define ServerOP_QSPlayerLogHandins 0x4011
#define ServerOP_QSPlayerLogNPCKills 0x4012
#define ServerOP_QSPlayerLogDeletes 0x4013
#define ServerOP_QSPlayerLogMoves 0x4014
#define ServerOP_QSPlayerLogMerchantTransactions 0x4015
#define ServerOP_QSSendQuery 0x4016
#define ServerOP_QSSendQuery 0x4016
#define ServerOP_CZSignalNPC 0x4017
#define ServerOP_CZSetEntityVariableByNPCTypeID 0x4018
/* Query Serv Generic Packet Flag/Type Enumeration */
enum { QSG_LFGuild = 0 };
@@ -1094,6 +1096,11 @@ struct CZClientSignal_Struct {
uint32 data;
};
struct CZNPCSignal_Struct {
uint32 npctype_id;
uint32 data;
};
struct CZClientSignalByName_Struct {
char Name[64];
uint32 data;
@@ -1235,6 +1242,12 @@ struct CZMessagePlayer_Struct {
char Message[512];
};
struct CZSetEntVarByNPCTypeID_Struct {
uint32 npctype_id;
char id[256];
char m_var[256];
};
struct ReloadWorld_Struct{
uint32 Option;
};
+44 -191
View File
@@ -1,6 +1,7 @@
#include <iostream>
#include <cstring>
#include <cstdlib>
#include <ctime>
#include "shareddb.h"
#include "mysql.h"
@@ -113,31 +114,12 @@ bool SharedDatabase::SetGMSpeed(uint32 account_id, uint8 gmspeed)
}
uint32 SharedDatabase::GetTotalTimeEntitledOnAccount(uint32 AccountID) {
uint32 EntitledTime = 0;
const char *EntitledQuery = "select sum(ascii(substring(profile, 237, 1)) + (ascii(substring(profile, 238, 1)) * 256) +"
"(ascii(substring(profile, 239, 1)) * 65536) + (ascii(substring(profile, 240, 1)) * 16777216))"
"from character_ where account_id = %i";
char errbuf[MYSQL_ERRMSG_SIZE];
char *query = 0;
MYSQL_RES *result;
MYSQL_ROW row;
if (RunQuery(query, MakeAnyLenString(&query, EntitledQuery, AccountID), errbuf, &result)) {
if (mysql_num_rows(result) == 1) {
row = mysql_fetch_row(result);
EntitledTime = atoi(row[0]);
}
mysql_free_result(result);
std::string query = StringFormat("SELECT `time_played` FROM `character_data` WHERE `account_id` = %u", AccountID);
auto results = QueryDatabase(query);
for (auto row = results.begin(); row != results.end(); ++row) {
EntitledTime += atoi(row[0]);
}
safe_delete_array(query);
return EntitledTime;
}
@@ -348,12 +330,11 @@ int32 SharedDatabase::GetSharedPlatinum(uint32 account_id)
return 0;
}
bool SharedDatabase::SetSharedPlatinum(uint32 account_id, int32 amount_to_add)
{
bool SharedDatabase::SetSharedPlatinum(uint32 account_id, int32 amount_to_add) {
char errbuf[MYSQL_ERRMSG_SIZE];
char *query = 0;
if (!RunQuery(query, MakeAnyLenString(&query, "UPDATE account SET sharedplat = sharedplat + %i WHERE id = %i", amount_to_add, account_id), errbuf)) {
if (!RunQuery(query, MakeAnyLenString(&query, "UPDATE `account` SET `sharedplat` = `sharedplat` + %i WHERE id = %i", amount_to_add, account_id), errbuf)) {
std::cerr << "Error in SetSharedPlatinum query '" << query << "' " << errbuf << std::endl;
safe_delete_array(query);
return false;
@@ -363,37 +344,26 @@ bool SharedDatabase::SetSharedPlatinum(uint32 account_id, int32 amount_to_add)
return true;
}
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)
{
char errbuf[MYSQL_ERRMSG_SIZE];
char* query = 0;
MYSQL_RES *result;
MYSQL_ROW row;
bool SharedDatabase::SetStartingItems(PlayerProfile_Struct* pp, Inventory* inv, uint32 si_race, uint32 si_class, uint32 si_deity, uint32 si_current_zone, char* si_name, int admin_level) {
const Item_Struct* myitem;
RunQuery
(
query,
MakeAnyLenString
(
&query,
"SELECT itemid, item_charges, slot FROM starting_items "
"WHERE (race = %i or race = 0) AND (class = %i or class = 0) AND "
"(deityid = %i or deityid=0) AND (zoneid = %i or zoneid = 0) AND "
"gm <= %i ORDER BY id",
si_race, si_class, si_deity, si_current_zone, admin_level
),
errbuf,
&result
);
safe_delete_array(query);
while((row = mysql_fetch_row(result))) {
int itemid = atoi(row[0]);
int charges = atoi(row[1]);
int slot = atoi(row[2]);
uint32 itemid = 0;
int32 charges = 0;
int32 slot = 0;
auto query = StringFormat(
"SELECT `itemid`, `item_charges`, `slot` FROM `starting_items`"
" WHERE (`race` = %i OR `race` = 0)"
" AND (`class` = %i OR `class` = 0)"
" AND (`deityid` = %i OR `deityid` = 0)"
" AND (`zoneid` = %i OR `zoneid` = 0)"
" AND gm <= %i ORDER BY id",
si_race, si_class, si_deity, si_current_zone, admin_level);
auto results = QueryDatabase(query);
for (auto row = results.begin(); row != results.end(); ++row) {
itemid = atoi(row[0]);
charges = atoi(row[1]);
slot = atoi(row[2]);
myitem = GetItem(itemid);
if(!myitem)
if(!myitem)
continue;
ItemInst* myinst = CreateBaseItem(myitem, charges);
if(slot < 0)
@@ -401,9 +371,6 @@ bool SharedDatabase::SetStartingItems(PlayerProfile_Struct* pp, Inventory* inv,
inv->PutItem(slot, *myinst);
safe_delete(myinst);
}
if(result) mysql_free_result(result);
return true;
}
@@ -420,7 +387,7 @@ bool SharedDatabase::GetSharedBank(uint32 id, Inventory* inv, bool is_charid) {
if (is_charid) {
len_query = MakeAnyLenString(&query,
"SELECT sb.slotid,sb.itemid,sb.charges,sb.augslot1,sb.augslot2,sb.augslot3,sb.augslot4,sb.augslot5,sb.custom_data from sharedbank sb "
"INNER JOIN character_ ch ON ch.account_id=sb.acctid "
"INNER JOIN character_data ch ON ch.account_id=sb.acctid "
"WHERE ch.id=%i", id);
}
else {
@@ -637,8 +604,13 @@ bool SharedDatabase::GetInventory(uint32 account_id, char* name, Inventory* inv)
bool ret = false;
// Retrieve character inventory
if (RunQuery(query, MakeAnyLenString(&query, "SELECT slotid,itemid,charges,color,augslot1,augslot2,augslot3,augslot4,augslot5,"
"instnodrop,custom_data FROM inventory INNER JOIN character_ ch ON ch.id=charid WHERE ch.name='%s' AND ch.account_id=%i ORDER BY slotid",
if (RunQuery(query, MakeAnyLenString(&query,
" SELECT `slotid`, `itemid`, `charges`, `color`, `augslot1`, `augslot2`, `augslot3`, `augslot4`, `augslot5`, `instnodrop`, `custom_data`"
" FROM `inventory`"
" INNER JOIN `character_data` ch ON ch.id = charid"
" WHERE ch.NAME = '%s'"
" AND ch.account_id = % i"
" ORDER BY `slotid`",
name, account_id), errbuf, &result))
{
while ((row = mysql_fetch_row(result))) {
@@ -698,7 +670,7 @@ bool SharedDatabase::GetInventory(uint32 account_id, char* name, Inventory* inv)
}
}
}
if (slot_id>=8000 && slot_id <= 8999)
if (slot_id >= 8000 && slot_id <= 8999)
put_slot_id = inv->PushCursor(*inst);
else
put_slot_id = inv->PutItem(slot_id, *inst);
@@ -1211,104 +1183,6 @@ bool SharedDatabase::LoadNPCFactionLists() {
return true;
}
// Get the player profile and inventory for the given account "account_id" and
// character name "name". Return true if the character was found, otherwise false.
// False will also be returned if there is a database error.
bool SharedDatabase::GetPlayerProfile(uint32 account_id, char* name, PlayerProfile_Struct* pp, Inventory* inv, ExtendedProfile_Struct *ext, char* current_zone, uint32 *current_instance) {
char errbuf[MYSQL_ERRMSG_SIZE];
char* query = 0;
MYSQL_RES* result;
MYSQL_ROW row;
bool ret = false;
unsigned long* lengths;
if (RunQuery(query, MakeAnyLenString(&query, "SELECT profile,zonename,x,y,z,extprofile,instanceid FROM character_ WHERE account_id=%i AND name='%s'", account_id, name), errbuf, &result)) {
if (mysql_num_rows(result) == 1) {
row = mysql_fetch_row(result);
lengths = mysql_fetch_lengths(result);
if (lengths[0] == sizeof(PlayerProfile_Struct)) {
memcpy(pp, row[0], sizeof(PlayerProfile_Struct));
if (current_zone)
strcpy(current_zone, row[1]);
pp->zone_id = GetZoneID(row[1]);
pp->x = atof(row[2]);
pp->y = atof(row[3]);
pp->z = atof(row[4]);
pp->zoneInstance = atoi(row[6]);
if (pp->x == -1 && pp->y == -1 && pp->z == -1)
GetSafePoints(pp->zone_id, GetInstanceVersion(pp->zoneInstance), &pp->x, &pp->y, &pp->z);
if(current_instance)
*current_instance = pp->zoneInstance;
if(ext) {
//SetExtendedProfile handles any conversion
SetExtendedProfile(ext, row[5], lengths[5]);
}
// Retrieve character inventory
ret = GetInventory(account_id, name, inv);
}
else {
LogFile->write(EQEMuLog::Error, "Player profile length mismatch in GetPlayerProfile. Found: %i, Expected: %i",
lengths[0], sizeof(PlayerProfile_Struct));
}
}
mysql_free_result(result);
}
else {
LogFile->write(EQEMuLog::Error, "GetPlayerProfile query '%s' %s", query, errbuf);
}
safe_delete_array(query);
return ret;
}
bool SharedDatabase::SetPlayerProfile(uint32 account_id, uint32 charid, PlayerProfile_Struct* pp, Inventory* inv, ExtendedProfile_Struct *ext, uint32 current_zone, uint32 current_instance, uint8 MaxXTargets) {
char errbuf[MYSQL_ERRMSG_SIZE];
char* query = 0;
uint32 affected_rows = 0;
bool ret = false;
if (RunQuery(query, SetPlayerProfile_MQ(&query, account_id, charid, pp, inv, ext, current_zone, current_instance, MaxXTargets), errbuf, 0, &affected_rows)) {
ret = (affected_rows != 0);
}
if (!ret) {
LogFile->write(EQEMuLog::Error, "SetPlayerProfile query '%s' %s", query, errbuf);
}
safe_delete_array(query);
return ret;
}
// Generate SQL for updating player profile
uint32 SharedDatabase::SetPlayerProfile_MQ(char** query, uint32 account_id, uint32 charid, PlayerProfile_Struct* pp, Inventory* inv, ExtendedProfile_Struct *ext, uint32 current_zone, uint32 current_instance, uint8 MaxXTargets) {
*query = new char[396 + sizeof(PlayerProfile_Struct)*2 + sizeof(ExtendedProfile_Struct)*2 + 4];
char* end = *query;
if (!current_zone)
current_zone = pp->zone_id;
if (!current_instance)
current_instance = pp->zoneInstance;
if(strlen(pp->name) == 0) // Sanity check in case pp never loaded
return false;
end += sprintf(end, "UPDATE character_ SET timelaston=unix_timestamp(now()),name=\'%s\', zonename=\'%s\', zoneid=%u, instanceid=%u, x = %f, y = %f, z = %f, profile=\'", pp->name, GetZoneName(current_zone), current_zone, current_instance, pp->x, pp->y, pp->z);
end += DoEscapeString(end, (char*)pp, sizeof(PlayerProfile_Struct));
end += sprintf(end,"\', extprofile=\'");
end += DoEscapeString(end, (char*)ext, sizeof(ExtendedProfile_Struct));
end += sprintf(end,"\',class=%d,level=%d,xtargets=%u WHERE id=%u", pp->class_, pp->level, MaxXTargets, charid);
return (uint32) (end - (*query));
}
// Create appropriate ItemInst class
ItemInst* SharedDatabase::CreateItem(uint32 item_id, int16 charges, uint32 aug1, uint32 aug2, uint32 aug3, uint32 aug4, uint32 aug5)
{
@@ -2120,40 +1994,19 @@ const LootDrop_Struct* SharedDatabase::GetLootDrop(uint32 lootdrop_id) {
return nullptr;
}
void SharedDatabase::GetPlayerInspectMessage(char* playername, InspectMessage_Struct* message) {
char errbuf[MYSQL_ERRMSG_SIZE];
char *query = 0;
MYSQL_RES *result;
MYSQL_ROW row;
if (RunQuery(query, MakeAnyLenString(&query, "SELECT inspectmessage FROM character_ WHERE name='%s'", playername), errbuf, &result)) {
safe_delete_array(query);
if (mysql_num_rows(result) == 1) {
row = mysql_fetch_row(result);
memcpy(message, row[0], sizeof(InspectMessage_Struct));
}
mysql_free_result(result);
}
else {
std::cerr << "Error in GetPlayerInspectMessage query '" << query << "' " << errbuf << std::endl;
safe_delete_array(query);
void SharedDatabase::LoadCharacterInspectMessage(uint32 character_id, InspectMessage_Struct* message) {
std::string query = StringFormat("SELECT `inspect_message` FROM `character_inspect_messages` WHERE `id` = %u LIMIT 1", character_id);
auto results = QueryDatabase(query); ThrowDBError(results.ErrorMessage(), "SharedDatabase::LoadCharacterInspectMessage", query);
auto row = results.begin();
memcpy(message, "", sizeof(InspectMessage_Struct));
for (auto row = results.begin(); row != results.end(); ++row) {
memcpy(message, row[0], sizeof(InspectMessage_Struct));
}
}
void SharedDatabase::SetPlayerInspectMessage(char* playername, const InspectMessage_Struct* message) {
char errbuf[MYSQL_ERRMSG_SIZE];
char *query = 0;
std::string msg = EscapeString(message->text);
if (!RunQuery(query, MakeAnyLenString(&query, "UPDATE character_ SET inspectmessage='%s' WHERE name='%s'", msg.c_str(), playername), errbuf)) {
std::cerr << "Error in SetPlayerInspectMessage query '" << query << "' " << errbuf << std::endl;
}
safe_delete_array(query);
void SharedDatabase::SaveCharacterInspectMessage(uint32 character_id, const InspectMessage_Struct* message) {
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); ThrowDBError(results.ErrorMessage(), "SharedDatabase::SaveCharacterInspectMessage", query);
}
void SharedDatabase::GetBotInspectMessage(uint32 botid, InspectMessage_Struct* message) {
+2 -5
View File
@@ -40,13 +40,10 @@ public:
bool SetGMSpeed(uint32 account_id, uint8 gmspeed);
uint8 GetGMSpeed(uint32 account_id);
bool SetHideMe(uint32 account_id, uint8 hideme);
bool GetPlayerProfile(uint32 account_id, char* name, PlayerProfile_Struct* pp, Inventory* inv, ExtendedProfile_Struct *ext, char* current_zone = 0, uint32 *current_instance = 0);
bool SetPlayerProfile(uint32 account_id, uint32 charid, PlayerProfile_Struct* pp, Inventory* inv, ExtendedProfile_Struct *ext, uint32 current_zone, uint32 current_instance, uint8 MaxXTargets);
uint32 SetPlayerProfile_MQ(char** query, uint32 account_id, uint32 charid, PlayerProfile_Struct* pp, Inventory* inv, ExtendedProfile_Struct *ext, uint32 current_zone, uint32 current_instance, uint8 MaxXTargets);
int32 DeleteStalePlayerCorpses();
int32 DeleteStalePlayerBackups();
void GetPlayerInspectMessage(char* playername, InspectMessage_Struct* message);
void SetPlayerInspectMessage(char* playername, const InspectMessage_Struct* message);
void LoadCharacterInspectMessage(uint32 character_id, InspectMessage_Struct* message);
void SaveCharacterInspectMessage(uint32 character_id, const InspectMessage_Struct* message);
void GetBotInspectMessage(uint32 botid, InspectMessage_Struct* message);
void SetBotInspectMessage(uint32 botid, const InspectMessage_Struct* message);
bool GetCommandSettings(std::map<std::string,uint8> &commands);
+56
View File
@@ -0,0 +1,56 @@
/* EQEMu: Everquest Server Emulator
Copyright (C) 2001-2002 EQEMu Development Team (http://eqemu.org)
This program is free software; 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 "types.h"
#include "skills.h"
bool EQEmu::IsTradeskill(SkillUseTypes skill)
{
switch (skill) {
case SkillFishing:
case SkillMakePoison:
case SkillTinkering:
case SkillResearch:
case SkillAlchemy:
case SkillBaking:
case SkillTailoring:
case SkillBlacksmithing:
case SkillFletching:
case SkillBrewing:
case SkillPottery:
case SkillJewelryMaking:
return true;
default:
return false;
}
}
bool EQEmu::IsSpecializedSkill(SkillUseTypes skill)
{
// this could be a simple if, but if this is more portable if any IDs change (probably won't)
// or any other specialized are added (also unlikely)
switch (skill) {
case SkillSpecializeAbjure:
case SkillSpecializeAlteration:
case SkillSpecializeConjuration:
case SkillSpecializeDivination:
case SkillSpecializeEvocation:
return true;
default:
return false;
}
}
+6
View File
@@ -260,4 +260,10 @@ typedef enum {
#define HIGHEST_SKILL FRENZY
*/
// for skill related helper functions
namespace EQEmu {
bool IsTradeskill(SkillUseTypes skill);
bool IsSpecializedSkill(SkillUseTypes skill);
}
#endif
+5
View File
@@ -17,6 +17,11 @@ StructStrategy::StructStrategy() {
}
void StructStrategy::Encode(EQApplicationPacket **p, EQStream *dest, bool ack_req) const {
if((*p)->GetOpcodeBypass() != 0) {
PassEncoder(p, dest, ack_req);
return;
}
EmuOpcode op = (*p)->GetOpcode();
Encoder proc = encoders[op];
proc(p, dest, ack_req);
+4
View File
@@ -8,18 +8,22 @@ SET(tests_sources
SET(tests_headers
atobool_test.h
data_verification_test.h
fixed_memory_test.h
fixed_memory_variable_test.h
hextoi_32_64_test.h
ipc_mutex_test.h
memory_mapped_file_test.h
string_util_test.h
skills_util_test.h
)
ADD_EXECUTABLE(tests ${tests_sources} ${tests_headers})
TARGET_LINK_LIBRARIES(tests common cppunit)
INSTALL(TARGETS tests RUNTIME DESTINATION ${CMAKE_INSTALL_PREFIX})
IF(MSVC)
SET_TARGET_PROPERTIES(tests PROPERTIES LINK_FLAGS_RELEASE "/OPT:REF /OPT:ICF")
TARGET_LINK_LIBRARIES(tests "Ws2_32.lib")
+108
View File
@@ -0,0 +1,108 @@
/* 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 __EQEMU_TESTS_DATA_VERIFICATION_H
#define __EQEMU_TESTS_DATA_VERIFICATION_H
#include "cppunit/cpptest.h"
#include "../common/data_verification.h"
class DataVerificationTest : public Test::Suite {
typedef void(DataVerificationTest::*TestFunction)(void);
public:
DataVerificationTest() {
TEST_ADD(DataVerificationTest::Clamp);
TEST_ADD(DataVerificationTest::ClampUpper);
TEST_ADD(DataVerificationTest::ClampLower);
TEST_ADD(DataVerificationTest::ValueWithin);
}
~DataVerificationTest() {
}
private:
void Clamp() {
float value_f = 500.0f;
int value_i = 500;
float vf1 = EQEmu::Clamp(value_f, 0.0f, 1000.0f);
float vf2 = EQEmu::Clamp(value_f, 0.0f, 250.0f);
float vf3 = EQEmu::Clamp(value_f, 750.0f, 1000.0f);
int vi1 = EQEmu::Clamp(value_i, 0, 1000);
int vi2 = EQEmu::Clamp(value_i, 0, 250);
int vi3 = EQEmu::Clamp(value_i, 750, 1000);
TEST_ASSERT_EQUALS(vf1, 500.0f);
TEST_ASSERT_EQUALS(vf2, 250.0f);
TEST_ASSERT_EQUALS(vf3, 750.0f);
TEST_ASSERT_EQUALS(vi1, 500);
TEST_ASSERT_EQUALS(vi2, 250);
TEST_ASSERT_EQUALS(vi3, 750);
}
void ClampUpper() {
float value_f = 500.0f;
int value_i = 500;
float vf1 = EQEmu::ClampUpper(value_f, 1000.0f);
float vf2 = EQEmu::ClampUpper(value_f, 250.0f);
int vi1 = EQEmu::ClampUpper(value_i, 1000);
int vi2 = EQEmu::ClampUpper(value_i, 250);
TEST_ASSERT_EQUALS(vf1, 500.0f);
TEST_ASSERT_EQUALS(vf2, 250.0f);
TEST_ASSERT_EQUALS(vi1, 500);
TEST_ASSERT_EQUALS(vi2, 250);
}
void ClampLower() {
float value_f = 500.0f;
int value_i = 500;
float vf1 = EQEmu::ClampLower(value_f, 0.0f);
float vf2 = EQEmu::ClampLower(value_f, 750.0f);
int vi1 = EQEmu::ClampLower(value_i, 0);
int vi2 = EQEmu::ClampLower(value_i, 750);
TEST_ASSERT_EQUALS(vf1, 500.0f);
TEST_ASSERT_EQUALS(vf2, 750.0f);
TEST_ASSERT_EQUALS(vi1, 500);
TEST_ASSERT_EQUALS(vi2, 750);
}
void ValueWithin() {
float value_f = 500.0f;
int value_i = 500;
TEST_ASSERT(EQEmu::ValueWithin(value_f, 0.0f, 1000.0f));
TEST_ASSERT(!EQEmu::ValueWithin(value_f, 0.0f, 400.0f));
TEST_ASSERT(!EQEmu::ValueWithin(value_f, 600.0f, 900.0f));
TEST_ASSERT(EQEmu::ValueWithin(value_i, 0, 1000));
TEST_ASSERT(!EQEmu::ValueWithin(value_i, 0, 400));
TEST_ASSERT(!EQEmu::ValueWithin(value_i, 600, 900));
}
};
#endif
+4
View File
@@ -27,6 +27,8 @@
#include "atobool_test.h"
#include "hextoi_32_64_test.h"
#include "string_util_test.h"
#include "data_verification_test.h"
#include "skills_util_test.h"
int main() {
try {
@@ -40,6 +42,8 @@ int main() {
tests.add(new atoboolTest());
tests.add(new hextoi_32_64_Test());
tests.add(new StringUtilTest());
tests.add(new DataVerificationTest());
tests.add(new SkillsUtilsTest());
tests.run(*output, true);
} catch(...) {
return -1;
+48
View File
@@ -0,0 +1,48 @@
/* 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 __EQEMU_TESTS_SKILLS_UTILS_H
#define __EQEMU_TESTS_SKILLS_UTILS_H
#include "cppunit/cpptest.h"
#include "../common/skills.h"
class SkillsUtilsTest: public Test::Suite {
typedef void(SkillsUtilsTest::*TestFunction)(void);
public:
SkillsUtilsTest() {
TEST_ADD(SkillsUtilsTest::IsTradeskill);
TEST_ADD(SkillsUtilsTest::IsSpecializedSkill);
}
~SkillsUtilsTest() {
}
private:
void IsTradeskill() {
TEST_ASSERT(EQEmu::IsTradeskill(SkillPottery));
TEST_ASSERT(!EQEmu::IsTradeskill(SkillParry));
}
void IsSpecializedSkill() {
TEST_ASSERT(EQEmu::IsSpecializedSkill(SkillSpecializeConjuration));
TEST_ASSERT(!EQEmu::IsSpecializedSkill(SkillConjuration))
}
};
#endif
+2 -2
View File
@@ -23,7 +23,7 @@
#include "../common/string_util.h"
class StringUtilTest : public Test::Suite {
typedef void(IPCMutexTest::*TestFunction)(void);
typedef void(StringUtilTest::*TestFunction)(void);
public:
StringUtilTest() {
TEST_ADD(StringUtilTest::StringFormatTest);
@@ -35,7 +35,7 @@ public:
}
private:
void StringFormatTest() {
void StringFormatTest() {
const char* fmt = "Test: %c %d %4.2f";
char c = 'a';
int i = 2014;
+4 -4
View File
@@ -139,7 +139,7 @@ int Database::FindAccount(const char *characterName, Client *client) {
client->ClearCharacters();
std::string query = StringFormat("SELECT `id`, `account_id`, `level` "
"FROM `character_` WHERE `name` = '%s' LIMIT 1",
"FROM `character_data` WHERE `name` = '%s' LIMIT 1",
characterName);
auto results = QueryDatabase(query);
if (!results.Success()) {
@@ -159,7 +159,7 @@ int Database::FindAccount(const char *characterName, Client *client) {
_log(UCS__TRACE, "Account ID for %s is %i", characterName, accountID);
query = StringFormat("SELECT `id`, `name`, `level` FROM `character_` "
query = StringFormat("SELECT `id`, `name`, `level` FROM `character_data` "
"WHERE `account_id` = %i AND `name` != '%s'",
accountID, characterName);
results = QueryDatabase(query);
@@ -174,7 +174,7 @@ int Database::FindAccount(const char *characterName, Client *client) {
bool Database::VerifyMailKey(std::string characterName, int IPAddress, std::string MailKey) {
std::string query = StringFormat("SELECT `mailkey` FROM `character_` WHERE `name`='%s' LIMIT 1",
std::string query = StringFormat("SELECT `mailkey` FROM `character_data` WHERE `name`='%s' LIMIT 1",
characterName.c_str());
auto results = QueryDatabase(query);
if (!results.Success()) {
@@ -202,7 +202,7 @@ bool Database::VerifyMailKey(std::string characterName, int IPAddress, std::stri
int Database::FindCharacter(const char *characterName) {
char *safeCharName = RemoveApostrophes(characterName);
std::string query = StringFormat("SELECT `id` FROM `character_` WHERE `name`='%s' LIMIT 1", safeCharName);
std::string query = StringFormat("SELECT `id` FROM `character_data` WHERE `name`='%s' LIMIT 1", safeCharName);
auto results = QueryDatabase(query);
if (!results.Success()) {
_log(UCS__ERROR, "FindCharacter failed. %s %s", query.c_str(), results.ErrorMessage().c_str());
+1 -1
View File
@@ -147,7 +147,7 @@ OP_Begging=0x13e7 # ShowEQ 10/27/05
OP_InspectRequest=0x775d # ShowEQ 10/27/05
OP_Action2=0x0000
OP_BeginCast=0x3990 # ShowEQ 10/27/05
OP_BuffFadeMsg=0x0b2d # ShowEQ 10/27/05
OP_ColoredText=0x0b2d # ShowEQ 10/27/05
OP_Consent=0x1081 # ShowEQ 10/27/05
OP_LFGCommand=0x68ac # ShowEQ 10/27/05
OP_LFGGetMatchesRequest=0x022f # ShowEQ 10/27/05
+1 -1
View File
@@ -150,7 +150,7 @@ OP_InspectRequest=0x2403
OP_Action2=0x0000 # ShowEQ 06/29/05
OP_BeginCast=0x3990 # ShowEQ 06/29/05
OP_WhoAllRequest=0x5cdd # ShowEQ 06/29/05
OP_BuffFadeMsg=0x4bc6 # ShowEQ 06/29/05
OP_ColoredText=0x4bc6 # ShowEQ 06/29/05
OP_Consent=0x1081 # ShowEQ 06/29/05
OP_LFGCommand=0x022f # ShowEQ 06/29/05
OP_LFGGetMatchesRequest=0x6f82 # ShowEQ 06/29/05
+1 -1
View File
@@ -166,7 +166,7 @@ OP_InspectRequest=0x23f1
OP_InspectAnswer=0x5794
OP_InspectMessageUpdate=0x3064
OP_BeginCast=0x17ff
OP_BuffFadeMsg=0x41cb
OP_ColoredText=0x41cb
OP_ConsentResponse=0x183d
OP_MemorizeSpell=0x2fac
OP_SwapSpell=0x4736
+2 -2
View File
@@ -168,7 +168,7 @@ OP_GMLastName=0x3563 # C
OP_InspectAnswer=0x4938 # C
OP_Action2=0x7e4d # C OP_Damage?
OP_BeginCast=0x0d5a # C
OP_BuffFadeMsg=0x569a # C
OP_ColoredText=0x569a # C
OP_ConsentResponse=0x6e47 # C
OP_MemorizeSpell=0x8543 # C
OP_SwapSpell=0x3fd2 # C
@@ -659,4 +659,4 @@ OP_RAWOutOfSession=0x0000 #
# we need to document the differences between these packets to make identifying them easier
OP_Some3ByteHPUpdate=0x0000 # initial HP update for mobs
OP_InitialHPUpdate=0x0000 #
OP_InitialHPUpdate=0x0000 #
+1 -1
View File
@@ -164,7 +164,7 @@ OP_GMLastName=0x0375 #/lastname <Name> <New Surname>
OP_InspectAnswer=0x084F #SEQ 12/04/08
OP_Action2=0x0EF2 #SEQ 12/04/08
OP_BeginCast=0x5A50 #SEQ 12/04/08
OP_BuffFadeMsg=0x3BC7 #SEQ 12/04/08
OP_ColoredText=0x3BC7 #SEQ 12/04/08
OP_ConsentResponse=0x4D30 #SEQ 12/04/08
OP_MemorizeSpell=0x6A93 #SEQ 12/04/08
OP_SwapSpell=0x1418 #SEQ 12/04/08
+1 -1
View File
@@ -154,7 +154,7 @@ OP_InspectRequest=0x775d # ShowEQ 10/27/05
OP_InspectAnswer=0x2403 # ShowEQ 10/27/05
OP_Action2=0x0000
OP_BeginCast=0x3990 # ShowEQ 10/27/05
OP_BuffFadeMsg=0x0b2d # ShowEQ 10/27/05
OP_ColoredText=0x0b2d # ShowEQ 10/27/05
OP_Consent=0x1081 # ShowEQ 10/27/05
OP_ConsentDeny=0x4e8c # ShowEQ 10/27/05
OP_ConsentResponse=0x6380 # ShowEQ 10/27/05
+1 -1
View File
@@ -168,7 +168,7 @@ OP_GMLastName=0x7bfb # C
OP_InspectAnswer=0x0c2b # C
OP_BeginCast=0x0d5a # C
OP_BuffFadeMsg=0x71bf # C
OP_ColoredText=0x71bf # C
OP_ConsentResponse=0x0e87 # C
OP_MemorizeSpell=0x3887 # C
OP_SwapSpell=0x5805 # C
@@ -0,0 +1 @@
INSERT INTO `rule_values` (`ruleset_id`, `rule_name`, `rule_value`, `notes`) VALUES (1, 'Spells:SHDProcIDOffByOne', 'true', 'SHD procs are off by 1. Set true for pre-UF spell files, false for UF+.');
@@ -0,0 +1 @@
INSERT INTO `rule_values` (`ruleset_id`, `rule_name`, `rule_value`, `notes`) VALUES (1, 'Spells:Jun182014HundredHandsRevamp', 'false', 'Set this to true if your spell file is from after June 18, 2014.');
@@ -0,0 +1 @@
ALTER TABLE `account` ADD COLUMN `ban_reason` TEXT NULL DEFAULT NULL AFTER `expansion`, ADD COLUMN `suspend_reason` TEXT NULL DEFAULT NULL AFTER `ban_reason`;
+1 -1
View File
@@ -1069,7 +1069,7 @@ void AdventureManager::LoadLeaderboardInfo()
leaderboard_info_percentage_tak.clear();
std::string query = "SELECT ch.name, ch.id, adv_stats.* FROM adventure_stats "
"AS adv_stats LEFT JOIN character_ AS ch ON adv_stats.player_id = ch.id;";
"AS adv_stats LEFT JOIN `character_data` AS ch ON adv_stats.player_id = ch.id;";
auto results = database.QueryDatabase(query);
if(!results.Success()) {
LogFile->write(EQEMuLog::Error, "Error in AdventureManager:::GetLeaderboardInfo: %s (%s)", query.c_str(), results.ErrorMessage().c_str());
+75 -130
View File
@@ -64,8 +64,6 @@ extern ClientList client_list;
extern uint32 numclients;
extern volatile bool RunLoops;
Client::Client(EQStreamInterface* ieqs)
: autobootup_timeout(RuleI(World, ZoneAutobootTimeoutMS)),
CLE_keepalive_timer(RuleI(World, ClientKeepaliveTimeoutMS)),
@@ -130,7 +128,7 @@ void Client::SendLogServer()
void Client::SendEnterWorld(std::string name)
{
char char_name[32]= { 0 };
char char_name[64] = { 0 };
if (pZoning && database.GetLiveChar(GetAccountID(), char_name)) {
if(database.GetAccountIDByChar(char_name) != GetAccountID()) {
eqs->Close();
@@ -174,7 +172,7 @@ void Client::SendCharInfo() {
EQApplicationPacket *outapp = new EQApplicationPacket(OP_SendCharInfo, sizeof(CharacterSelect_Struct));
CharacterSelect_Struct* cs = (CharacterSelect_Struct*)outapp->pBuffer;
database.GetCharSelectInfo(GetAccountID(), cs);
database.GetCharSelectInfo(GetAccountID(), cs, ClientVersionBit);
QueuePacket(outapp);
safe_delete(outapp);
@@ -471,8 +469,8 @@ bool Client::HandleSendLoginInfoPacket(const EQApplicationPacket *app) {
return true;
}
bool Client::HandleNameApprovalPacket(const EQApplicationPacket *app) {
bool Client::HandleNameApprovalPacket(const EQApplicationPacket *app)
{
if (GetAccountID() == 0) {
clog(WORLD__CLIENT_ERR,"Name approval request with no logged in account");
return false;
@@ -482,7 +480,7 @@ bool Client::HandleNameApprovalPacket(const EQApplicationPacket *app) {
uchar race = app->pBuffer[64];
uchar clas = app->pBuffer[68];
clog(WORLD__CLIENT,"Name approval request. Name=%s, race=%s, class=%s",char_name,GetRaceName(race),GetEQClassName(clas));
clog(WORLD__CLIENT, "Name approval request. Name=%s, race=%s, class=%s", char_name, GetRaceName(race), GetEQClassName(clas));
EQApplicationPacket *outapp;
outapp = new EQApplicationPacket;
@@ -490,27 +488,27 @@ bool Client::HandleNameApprovalPacket(const EQApplicationPacket *app) {
outapp->pBuffer = new uchar[1];
outapp->size = 1;
bool valid;
if(!database.CheckNameFilter(char_name)) {
valid = false;
bool valid = false;
if(!database.CheckNameFilter(char_name)) {
valid = false;
}
else if(char_name[0] < 'A' && char_name[0] > 'Z') {
//name must begin with an upper-case letter.
valid = false;
/* Name must begin with an upper-case letter. */
else if (islower(char_name[0])) {
valid = false;
}
else if (database.ReserveName(GetAccountID(), char_name)) {
valid = true;
}
else if (database.ReserveName(GetAccountID(), char_name)) {
valid = true;
}
else {
valid = false;
else {
valid = false;
}
outapp->pBuffer[0] = valid? 1 : 0;
QueuePacket(outapp);
safe_delete(outapp);
if(!valid) {
if (!valid)
memset(char_name, 0, sizeof(char_name));
}
return true;
}
@@ -642,13 +640,11 @@ bool Client::HandleCharacterCreateRequestPacket(const EQApplicationPacket *app)
}
bool Client::HandleCharacterCreatePacket(const EQApplicationPacket *app) {
if (GetAccountID() == 0)
{
if (GetAccountID() == 0) {
clog(WORLD__CLIENT_ERR,"Account ID not set; unable to create character.");
return false;
}
else if (app->size != sizeof(CharCreate_Struct))
{
else if (app->size != sizeof(CharCreate_Struct)) {
clog(WORLD__CLIENT_ERR,"Wrong size on OP_CharacterCreate. Got: %d, Expected: %d",app->size,sizeof(CharCreate_Struct));
DumpPacket(app);
// the previous behavior was essentially returning true here
@@ -657,8 +653,7 @@ bool Client::HandleCharacterCreatePacket(const EQApplicationPacket *app) {
}
CharCreate_Struct *cc = (CharCreate_Struct*)app->pBuffer;
if(OPCharCreate(char_name, cc) == false)
{
if(OPCharCreate(char_name, cc) == false) {
database.DeleteCharacter(char_name);
EQApplicationPacket *outapp = new EQApplicationPacket(OP_ApproveName, 1);
outapp->pBuffer[0] = 0;
@@ -675,8 +670,7 @@ bool Client::HandleCharacterCreatePacket(const EQApplicationPacket *app) {
return true;
}
bool Client::HandleEnterWorldPacket(const EQApplicationPacket *app) {
bool Client::HandleEnterWorldPacket(const EQApplicationPacket *app) {
if (GetAccountID() == 0) {
clog(WORLD__CLIENT_ERR,"Enter world with no logged in account");
eqs->Close();
@@ -713,11 +707,10 @@ bool Client::HandleEnterWorldPacket(const EQApplicationPacket *app) {
return true;
}
if(!pZoning && ew->return_home && !ew->tutorial)
{
if(!pZoning && ew->return_home && !ew->tutorial) {
CharacterSelect_Struct* cs = new CharacterSelect_Struct;
memset(cs, 0, sizeof(CharacterSelect_Struct));
database.GetCharSelectInfo(GetAccountID(), cs);
database.GetCharSelectInfo(GetAccountID(), cs, ClientVersionBit);
bool home_enabled = false;
for(int x = 0; x < 10; ++x)
@@ -733,12 +726,10 @@ bool Client::HandleEnterWorldPacket(const EQApplicationPacket *app) {
}
safe_delete(cs);
if(home_enabled)
{
if(home_enabled) {
zoneID = database.MoveCharacterToBind(charid,4);
}
else
{
else {
clog(WORLD__CLIENT_ERR,"'%s' is trying to go home before they're able...",char_name);
database.SetHackerFlag(GetAccountName(), char_name, "MQGoHome: player tried to go home before they were able.");
eqs->Close();
@@ -749,7 +740,7 @@ bool Client::HandleEnterWorldPacket(const EQApplicationPacket *app) {
if(!pZoning && (RuleB(World, EnableTutorialButton) && (ew->tutorial || StartInTutorial))) {
CharacterSelect_Struct* cs = new CharacterSelect_Struct;
memset(cs, 0, sizeof(CharacterSelect_Struct));
database.GetCharSelectInfo(GetAccountID(), cs);
database.GetCharSelectInfo(GetAccountID(), cs, ClientVersionBit);
bool tutorial_enabled = false;
for(int x = 0; x < 10; ++x)
@@ -807,16 +798,16 @@ bool Client::HandleEnterWorldPacket(const EQApplicationPacket *app) {
database.SetLoginFlags(charid, false, false, 1);
}
else{
uint32 groupid=database.GetGroupID(char_name);
if(groupid>0){
char* leader=0;
char leaderbuf[64]={0};
if((leader=database.GetGroupLeaderForLogin(char_name,leaderbuf)) && strlen(leader)>1){
uint32 groupid = database.GetGroupID(char_name);
if(groupid > 0){
char* leader = 0;
char leaderbuf[64] = {0};
if((leader = database.GetGroupLeaderForLogin(char_name, leaderbuf)) && strlen(leader)>1){
EQApplicationPacket* outapp3 = new EQApplicationPacket(OP_GroupUpdate,sizeof(GroupJoin_Struct));
GroupJoin_Struct* gj=(GroupJoin_Struct*)outapp3->pBuffer;
gj->action=8;
strcpy(gj->yourname,char_name);
strcpy(gj->membername,leader);
strcpy(gj->yourname, char_name);
strcpy(gj->membername, leader);
QueuePacket(outapp3);
safe_delete(outapp3);
}
@@ -895,8 +886,7 @@ bool Client::HandleEnterWorldPacket(const EQApplicationPacket *app) {
bool Client::HandleDeleteCharacterPacket(const EQApplicationPacket *app) {
uint32 char_acct_id = database.GetAccountIDByChar((char*)app->pBuffer);
if(char_acct_id == GetAccountID())
{
if(char_acct_id == GetAccountID()) {
clog(WORLD__CLIENT,"Delete character: %s",app->pBuffer);
database.DeleteCharacter((char *)app->pBuffer);
SendCharInfo();
@@ -1347,8 +1337,7 @@ void Client::SendApproveWorld()
safe_delete(outapp);
}
bool Client::OPCharCreate(char *name, CharCreate_Struct *cc)
{
bool Client::OPCharCreate(char *name, CharCreate_Struct *cc) {
PlayerProfile_Struct pp;
ExtendedProfile_Struct ext;
Inventory inv;
@@ -1356,12 +1345,11 @@ bool Client::OPCharCreate(char *name, CharCreate_Struct *cc)
char startzone[50]={0};
uint32 i;
struct in_addr in;
int stats_sum = cc->STR + cc->STA + cc->AGI + cc->DEX +
cc->WIS + cc->INT + cc->CHA;
int stats_sum = cc->STR + cc->STA + cc->AGI + cc->DEX + cc->WIS + cc->INT + cc->CHA;
in.s_addr = GetIP();
clog(WORLD__CLIENT,"Character creation request from %s LS#%d (%s:%d) : ", GetCLE()->LSName(), GetCLE()->LSID(), inet_ntoa(in), GetPort());
clog(WORLD__CLIENT,"Name: %s", name);
clog(WORLD__CLIENT,"Race: %d Class: %d Gender: %d Deity: %d Start zone: %d",
@@ -1374,38 +1362,23 @@ bool Client::OPCharCreate(char *name, CharCreate_Struct *cc)
clog(WORLD__CLIENT,"Hairstyle: %d Haircolor: %d", cc->hairstyle, cc->haircolor);
clog(WORLD__CLIENT,"Beard: %d Beardcolor: %d", cc->beard, cc->beardcolor);
// validate the char creation struct
/* Validate the char creation struct */
if(ClientVersionBit & BIT_SoFAndLater) {
if(!CheckCharCreateInfoSoF(cc))
{
if(!CheckCharCreateInfoSoF(cc)) {
clog(WORLD__CLIENT_ERR,"CheckCharCreateInfo did not validate the request (bad race/class/stats)");
return false;
}
} else {
if(!CheckCharCreateInfoTitanium(cc))
{
if(!CheckCharCreateInfoTitanium(cc)) {
clog(WORLD__CLIENT_ERR,"CheckCharCreateInfo did not validate the request (bad race/class/stats)");
return false;
}
}
// Convert incoming cc_s to the new PlayerProfile_Struct
/* Convert incoming cc_s to the new PlayerProfile_Struct */
memset(&pp, 0, sizeof(PlayerProfile_Struct)); // start building the profile
InitExtendedProfile(&ext);
strn0cpy(pp.name, name, 63);
// clean the capitalization of the name
#if 0 // on second thought, don't - this will just make the creation fail
// because the name won't match what was already reserved earlier
for (i = 0; pp.name[i] && i < 63; i++)
{
if(!isalpha(pp.name[i]))
return false;
pp.name[i] = tolower(pp.name[i]);
}
pp.name[0] = toupper(pp.name[0]);
#endif
pp.race = cc->race;
pp.class_ = cc->class_;
@@ -1432,20 +1405,14 @@ bool Client::OPCharCreate(char *name, CharCreate_Struct *cc)
pp.lastlogin = bday;
pp.level = 1;
pp.points = 5;
pp.cur_hp = 1000; // 1k hp during dev only
//what was the point of this? zone dosent handle this:
//pp.expAA = 0xFFFFFFFF;
pp.cur_hp = 1000; // 1k hp during dev only
pp.hunger_level = 6000;
pp.thirst_level = 6000;
// FIXME: FV roleplay, database goodness...
// Racial Languages
SetRacialLanguages( &pp ); // bUsh
SetRaceStartingSkills( &pp ); // bUsh
SetClassStartingSkills( &pp ); // bUsh
/* Racial Languages */
SetRacialLanguages( &pp );
SetRaceStartingSkills( &pp );
SetClassStartingSkills( &pp );
SetClassLanguages(&pp);
pp.skills[SkillSenseHeading] = 200;
// Some one fucking fix this to use a field name. -Doodman
@@ -1453,24 +1420,25 @@ bool Client::OPCharCreate(char *name, CharCreate_Struct *cc)
// strcpy(pp.servername, WorldConfig::get()->ShortName.c_str());
for(i = 0; i < MAX_PP_SPELLBOOK; i++)
for (i = 0; i < MAX_PP_REF_SPELLBOOK; i++)
pp.spell_book[i] = 0xFFFFFFFF;
for(i = 0; i < MAX_PP_MEMSPELL; i++)
for(i = 0; i < MAX_PP_REF_MEMSPELL; i++)
pp.mem_spells[i] = 0xFFFFFFFF;
for(i = 0; i < BUFF_COUNT; i++)
pp.buffs[i].spellid = 0xFFFF;
/*
Was memset(pp.unknown3704, 0xffffffff, 8);
but I dont think thats what you really wanted to do...
memset is byte based
*/
//was memset(pp.unknown3704, 0xffffffff, 8);
//but I dont think thats what you really wanted to do...
//memset is byte based
//If server is PVP by default, make all character set to it.
/* If server is PVP by default, make all character set to it. */
pp.pvp = database.GetServerType() == 1 ? 1 : 0;
//If it is an SoF Client and the SoF Start Zone rule is set, send new chars there
/* If it is an SoF Client and the SoF Start Zone rule is set, send new chars there */
if((ClientVersionBit & BIT_SoFAndLater) && (RuleI(World, SoFStartZoneID) > 0)) {
clog(WORLD__CLIENT,"Found 'SoFStartZoneID' rule setting: %i", (RuleI(World, SoFStartZoneID)));
pp.zone_id = (RuleI(World, SoFStartZoneID));
@@ -1479,11 +1447,9 @@ bool Client::OPCharCreate(char *name, CharCreate_Struct *cc)
else
clog(WORLD__CLIENT_ERR,"Error getting zone id for Zone ID %i", (RuleI(World, SoFStartZoneID)));
}
else
{
// if there's a startzone variable put them in there
if(database.GetVariable("startzone", startzone, 50))
{
else {
/* if there's a startzone variable put them in there */
if(database.GetVariable("startzone", startzone, 50)) {
clog(WORLD__CLIENT,"Found 'startzone' variable setting: %s", startzone);
pp.zone_id = database.GetZoneID(startzone);
if(pp.zone_id)
@@ -1491,8 +1457,7 @@ bool Client::OPCharCreate(char *name, CharCreate_Struct *cc)
else
clog(WORLD__CLIENT_ERR,"Error getting zone id for '%s'", startzone);
}
else // otherwise use normal starting zone logic
{
else{ /* otherwise use normal starting zone logic */
bool ValidStartZone = false;
if(ClientVersionBit & BIT_TitaniumAndEarlier)
@@ -1505,14 +1470,12 @@ bool Client::OPCharCreate(char *name, CharCreate_Struct *cc)
}
}
if(!pp.zone_id)
{
if(!pp.zone_id) {
pp.zone_id = 1; // qeynos
pp.x = pp.y = pp.z = -1;
}
if(!pp.binds[0].zoneId)
{
if(!pp.binds[0].zoneId) {
pp.binds[0].zoneId = pp.zone_id;
pp.binds[0].x = pp.x;
pp.binds[0].y = pp.y;
@@ -1520,7 +1483,7 @@ bool Client::OPCharCreate(char *name, CharCreate_Struct *cc)
pp.binds[0].heading = pp.heading;
}
// set starting city location to the initial bind point
/* Set Starting city */
pp.binds[4] = pp.binds[0];
@@ -1529,28 +1492,23 @@ bool Client::OPCharCreate(char *name, CharCreate_Struct *cc)
clog(WORLD__CLIENT,"Bind location: %s %0.2f, %0.2f, %0.2f",
database.GetZoneName(pp.binds[0].zoneId), pp.binds[0].x, pp.binds[0].y, pp.binds[0].z);
// Starting Items inventory
/* Starting Items inventory */
database.SetStartingItems(&pp, &inv, pp.race, pp.class_, pp.deity, pp.zone_id, pp.name, GetAdmin());
// now we give the pp and the inv we made to StoreCharacter
// to see if we can store it
if (!database.StoreCharacter(GetAccountID(), &pp, &inv, &ext))
{
if (!database.StoreCharacter(GetAccountID(), &pp, &inv)) {
clog(WORLD__CLIENT_ERR,"Character creation failed: %s", pp.name);
return false;
}
else
{
else {
clog(WORLD__CLIENT,"Character creation successful: %s", pp.name);
return true;
}
}
// returns true if the request is ok, false if there's an error
bool CheckCharCreateInfoSoF(CharCreate_Struct *cc)
{
bool CheckCharCreateInfoSoF(CharCreate_Struct *cc) {
if(!cc) return false;
_log(WORLD__CLIENT, "Validating char creation info...");
@@ -1832,28 +1790,15 @@ bool CheckCharCreateInfoTitanium(CharCreate_Struct *cc)
return Charerrors == 0;
}
void Client::SetClassStartingSkills( PlayerProfile_Struct *pp )
void Client::SetClassStartingSkills(PlayerProfile_Struct *pp)
{
for(uint32 i = 0; i <= HIGHEST_SKILL; ++i) {
if(pp->skills[i] == 0) {
if(i >= SkillSpecializeAbjure && i <= SkillSpecializeEvocation) {
for (uint32 i = 0; i <= HIGHEST_SKILL; ++i) {
if (pp->skills[i] == 0) {
// Skip specialized, tradeskills (fishing excluded), Alcohol Tolerance, and Bind Wound
if (EQEmu::IsSpecializedSkill((SkillUseTypes)i) ||
(EQEmu::IsTradeskill((SkillUseTypes)i) && i != SkillFishing) ||
i == SkillAlcoholTolerance || i == SkillBindWound)
continue;
}
if(i == SkillMakePoison ||
i == SkillTinkering ||
i == SkillResearch ||
i == SkillAlchemy ||
i == SkillBaking ||
i == SkillTailoring ||
i == SkillBlacksmithing ||
i == SkillFletching ||
i == SkillBrewing ||
i == SkillPottery ||
i == SkillJewelryMaking ||
i == SkillBegging) {
continue;
}
pp->skills[i] = database.GetSkillCap(pp->class_, (SkillUseTypes)i, 1);
}
+4 -1
View File
@@ -113,7 +113,7 @@ bool Console::SendChannelMessage(const ServerChannelMessage_Struct* scm) {
break;
}
case 7: {
SendMessage(1, "%s tells you, '%s'", scm->from, scm->message);
SendMessage(1, "[%s] tells you, '%s'", scm->from, scm->message);
ServerPacket* pack = new ServerPacket(ServerOP_ChannelMessage, sizeof(ServerChannelMessage_Struct) + strlen(scm->message) + 1);
memcpy(pack->pBuffer, scm, pack->size);
ServerChannelMessage_Struct* scm2 = (ServerChannelMessage_Struct*) pack->pBuffer;
@@ -847,6 +847,9 @@ void Console::ProcessCommand(const char* command) {
zoneserver_list.SendPacket(pack);
safe_delete(pack);
}
else if (strcasecmp(sep.arg[0], "") == 0){
/* Hit Enter with no command */
}
else {
SendMessage(1, "Command unknown.");
}
+7 -7
View File
@@ -67,7 +67,6 @@
#endif
#include "../common/dbasync.h"
#include "../common/emu_tcp_server.h"
#include "../common/patches/patches.h"
#include "zoneserver.h"
@@ -98,7 +97,6 @@ UCSConnection UCSLink;
QueryServConnection QSLink;
LauncherList launcher_list;
AdventureManager adventure_manager;
DBAsync *dbasync = nullptr;
volatile bool RunLoops = true;
uint32 numclients = 0;
uint32 numzones = 0;
@@ -175,7 +173,6 @@ int main(int argc, char** argv) {
_log(WORLD__INIT_ERR, "Cannot continue without a database connection.");
return 1;
}
dbasync = new DBAsync(&database);
guild_mgr.SetDatabase(&database);
if (argc >= 2) {
@@ -222,9 +219,8 @@ int main(int argc, char** argv) {
else if (strcasecmp(argv[1], "flag") == 0) {
if (argc == 4) {
if (Seperator::IsNumber(argv[3])) {
if (atoi(argv[3]) >= 0 && atoi(argv[3]) <= 255) {
if (database.SetAccountStatus(argv[2], atoi(argv[3]))) {
if (database.SetAccountStatus(argv[2], atoi(argv[3]))){
std::cout << "Account flagged: Username='" << argv[2] << "', status=" << argv[3] << std::endl;
return 0;
}
@@ -276,6 +272,8 @@ int main(int argc, char** argv) {
_log(WORLD__INIT, "HTTP world service disabled.");
}
_log(WORLD__INIT, "Checking Database Conversions..");
database.CheckDatabaseConversions();
_log(WORLD__INIT, "Loading variables..");
database.LoadVariables();
_log(WORLD__INIT, "Loading zones..");
@@ -286,9 +284,11 @@ int main(int argc, char** argv) {
database.ClearRaid();
database.ClearRaidDetails();
_log(WORLD__INIT, "Loading items..");
if (!database.LoadItems()) {
if (!database.LoadItems())
_log(WORLD__INIT_ERR, "Error: Could not load item data. But ignoring");
}
_log(WORLD__INIT, "Loading skill caps..");
if (!database.LoadSkillCaps())
_log(WORLD__INIT_ERR, "Error: Could not load skill cap data. But ignoring");
_log(WORLD__INIT, "Loading guilds..");
guild_mgr.LoadGuilds();
//rules:
+176 -225
View File
@@ -21,7 +21,6 @@
#include "../common/string_util.h"
#include "../common/eq_packet_structs.h"
#include "../common/item.h"
#include "../common/dbasync.h"
#include "../common/rulesys.h"
#include <iostream>
#include <cstdlib>
@@ -34,248 +33,196 @@ extern std::vector<RaceClassCombos> character_create_race_class_combos;
// solar: the current stuff is at the bottom of this function
void WorldDatabase::GetCharSelectInfo(uint32 account_id, CharacterSelect_Struct* cs) {
char errbuf[MYSQL_ERRMSG_SIZE];
char* query = 0;
MYSQL_RES *result;
MYSQL_ROW row;
void WorldDatabase::GetCharSelectInfo(uint32 account_id, CharacterSelect_Struct* cs, uint32 ClientVersion) {
Inventory *inv;
uint8 has_home = 0;
uint8 has_bind = 0;
/* Initialize Variables */
for (int i=0; i<10; i++) {
strcpy(cs->name[i], "<none>");
cs->zone[i] = 0;
cs->level[i] = 0;
cs->tutorial[i] = 0;
cs->tutorial[i] = 0;
cs->gohome[i] = 0;
}
int char_num = 0;
unsigned long* lengths;
/* Get Character Info */
std::string cquery = StringFormat(
"SELECT "
"`id`, " // 0
"name, " // 1
"gender, " // 2
"race, " // 3
"class, " // 4
"`level`, " // 5
"deity, " // 6
"last_login, " // 7
"time_played, " // 8
"hair_color, " // 9
"beard_color, " // 10
"eye_color_1, " // 11
"eye_color_2, " // 12
"hair_style, " // 13
"beard, " // 14
"face, " // 15
"drakkin_heritage, " // 16
"drakkin_tattoo, " // 17
"drakkin_details, " // 18
"zone_id " // 19
"FROM "
"character_data "
"WHERE `account_id` = %i ORDER BY `name` LIMIT 10 ", account_id);
auto results = database.QueryDatabase(cquery); int char_num = 0;
for (auto row = results.begin(); row != results.end(); ++row) {
PlayerProfile_Struct pp;
memset(&pp, 0, sizeof(PlayerProfile_Struct));
// Populate character info
if (RunQuery(query, MakeAnyLenString(&query, "SELECT name,profile,zonename,class,level FROM character_ WHERE account_id=%i order by name limit 10", account_id), errbuf, &result)) {
safe_delete_array(query);
while ((row = mysql_fetch_row(result))) {
lengths = mysql_fetch_lengths(result);
////////////
//////////// This is the current one, the other are for converting
////////////
if ((lengths[1] == sizeof(PlayerProfile_Struct))) {
strcpy(cs->name[char_num], row[0]);
PlayerProfile_Struct* pp = (PlayerProfile_Struct*)row[1];
uint8 clas = atoi(row[3]);
uint8 lvl = atoi(row[4]);
uint32 character_id = atoi(row[0]);
strcpy(cs->name[char_num], row[1]);
uint8 lvl = atoi(row[5]);
cs->level[char_num] = lvl;
cs->class_[char_num] = atoi(row[4]);
cs->race[char_num] = atoi(row[3]);
cs->gender[char_num] = atoi(row[2]);
cs->deity[char_num] = atoi(row[6]);
cs->zone[char_num] = atoi(row[19]);
cs->face[char_num] = atoi(row[15]);
cs->haircolor[char_num] = atoi(row[9]);
cs->beardcolor[char_num] = atoi(row[10]);
cs->eyecolor2[char_num] = atoi(row[12]);
cs->eyecolor1[char_num] = atoi(row[11]);
cs->hairstyle[char_num] = atoi(row[13]);
cs->beard[char_num] = atoi(row[14]);
cs->drakkin_heritage[char_num] = atoi(row[16]);
cs->drakkin_tattoo[char_num] = atoi(row[17]);
cs->drakkin_details[char_num] = atoi(row[18]);
// Character information
if(lvl == 0)
cs->level[char_num] = pp->level; //no level in DB, trust PP
else
cs->level[char_num] = lvl;
if(clas == 0)
cs->class_[char_num] = pp->class_; //no class in DB, trust PP
else
cs->class_[char_num] = clas;
cs->race[char_num] = pp->race;
cs->gender[char_num] = pp->gender;
cs->deity[char_num] = pp->deity;
cs->zone[char_num] = GetZoneID(row[2]);
cs->face[char_num] = pp->face;
cs->haircolor[char_num] = pp->haircolor;
cs->beardcolor[char_num] = pp->beardcolor;
cs->eyecolor2[char_num] = pp->eyecolor2;
cs->eyecolor1[char_num] = pp->eyecolor1;
cs->hairstyle[char_num] = pp->hairstyle;
cs->beard[char_num] = pp->beard;
cs->drakkin_heritage[char_num] = pp->drakkin_heritage;
cs->drakkin_tattoo[char_num] = pp->drakkin_tattoo;
cs->drakkin_details[char_num] = pp->drakkin_details;
if (RuleB(World, EnableTutorialButton) && (lvl <= RuleI(World, MaxLevelForTutorial)))
cs->tutorial[char_num] = 1;
if(RuleB(World, EnableTutorialButton) && (lvl <= RuleI(World, MaxLevelForTutorial)))
cs->tutorial[char_num] = 1;
if (RuleB(World, EnableReturnHomeButton)) {
int now = time(nullptr);
if ((now - atoi(row[8])) >= RuleI(World, MinOfflineTimeToReturnHome))
cs->gohome[char_num] = 1;
}
if(RuleB(World, EnableReturnHomeButton)) {
int now = time(nullptr);
if((now - pp->lastlogin) >= RuleI(World, MinOfflineTimeToReturnHome))
cs->gohome[char_num] = 1;
/* Set Bind Point Data for any character that may possibly be missing it for any reason */
cquery = StringFormat("SELECT `zone_id`, `instance_id`, `x`, `y`, `z`, `heading`, `is_home` FROM `character_bind` WHERE `id` = %i LIMIT 2", character_id);
auto results_bind = database.QueryDatabase(cquery); has_home = 0; has_bind = 0;
for (auto row_b = results_bind.begin(); row_b != results_bind.end(); ++row_b) {
if (row_b[6] && atoi(row_b[6]) == 1){ has_home = 1; }
if (row_b[6] && atoi(row_b[6]) == 0){ has_bind = 1; }
}
if (has_home == 0 || has_bind == 0){
cquery = StringFormat("SELECT `zone_id`, `bind_id`, `x`, `y`, `z` FROM `start_zones` WHERE `player_class` = %i AND `player_deity` = %i AND `player_race` = %i",
cs->class_[char_num], cs->deity[char_num], cs->race[char_num]);
auto results_bind = database.QueryDatabase(cquery);
for (auto row_d = results_bind.begin(); row_d != results_bind.end(); ++row_d) {
/* If a bind_id is specified, make them start there */
if (atoi(row_d[1]) != 0) {
pp.binds[4].zoneId = (uint32)atoi(row_d[1]);
GetSafePoints(pp.binds[4].zoneId, 0, &pp.binds[4].x, &pp.binds[4].y, &pp.binds[4].z);
}
// This part creates home city entries for characters created before the home bind point was tracked.
// Do it here because the player profile is already loaded and it's as good a spot as any. This whole block should
// probably be removed at some point, when most accounts are safely converted.
if(pp->binds[4].zoneId == 0) {
bool altered = false;
MYSQL_RES *result2;
MYSQL_ROW row2;
char startzone[50] = {0};
// check for start zone variable (I didn't even know any variables were still being used...)
if(database.GetVariable("startzone", startzone, 50)) {
uint32 zoneid = database.GetZoneID(startzone);
if(zoneid) {
pp->binds[4].zoneId = zoneid;
GetSafePoints(zoneid, 0, &pp->binds[4].x, &pp->binds[4].y, &pp->binds[4].z);
altered = true;
}
}
else {
RunQuery(query,
MakeAnyLenString(&query,
"SELECT zone_id,bind_id,x,y,z FROM start_zones "
"WHERE player_class=%i AND player_deity=%i AND player_race=%i",
pp->class_,
pp->deity,
pp->race
),
errbuf,
&result2
);
safe_delete_array(query);
// if there is only one possible start city, set it
if(mysql_num_rows(result2) == 1) {
row2 = mysql_fetch_row(result2);
if(atoi(row2[1]) != 0) { // if a bind_id is specified, make them start there
pp->binds[4].zoneId = (uint32)atoi(row2[1]);
GetSafePoints(pp->binds[4].zoneId, 0, &pp->binds[4].x, &pp->binds[4].y, &pp->binds[4].z);
}
else { // otherwise, use the zone and coordinates given
pp->binds[4].zoneId = (uint32)atoi(row2[0]);
float x = atof(row2[2]);
float y = atof(row2[3]);
float z = atof(row2[4]);
if(x == 0 && y == 0 && z == 0)
GetSafePoints(pp->binds[4].zoneId, 0, &x, &y, &z);
pp->binds[4].x = x;
pp->binds[4].y = y;
pp->binds[4].z = z;
}
altered = true;
}
mysql_free_result(result2);
}
// update the player profile
if(altered) {
uint32 char_id = GetCharacterID(cs->name[char_num]);
RunQuery(query,MakeAnyLenString(&query,"SELECT extprofile FROM character_ WHERE id=%i",char_id), errbuf, &result2);
safe_delete_array(query);
if(result2) {
row2 = mysql_fetch_row(result2);
ExtendedProfile_Struct* ext = (ExtendedProfile_Struct*)row2[0];
SetPlayerProfile(account_id,char_id,pp,inv,ext, 0, 0, 5);
}
mysql_free_result(result2);
}
} // end of "set start zone" block
// Character's equipped items
// @merth: Haven't done bracer01/bracer02 yet.
// Also: this needs a second look after items are a little more solid
// NOTE: items don't have a color, players MAY have a tint, if the
// use_tint part is set. otherwise use the regular color
inv = new Inventory;
if(GetInventory(account_id, cs->name[char_num], inv))
{
for (uint8 material = 0; material <= 8; material++)
{
uint32 color;
ItemInst *item = inv->GetItem(Inventory::CalcSlotFromMaterial(material));
if(item == 0)
continue;
cs->equip[char_num][material] = item->GetItem()->Material;
if(pp->item_tint[material].rgb.use_tint) // they have a tint (LoY dye)
color = pp->item_tint[material].color;
else // no tint, use regular item color
color = item->GetItem()->Color;
cs->cs_colors[char_num][material].color = color;
// the weapons are kept elsewhere
if ((material==MaterialPrimary) || (material==MaterialSecondary))
{
if(strlen(item->GetItem()->IDFile) > 2) {
uint32 idfile=atoi(&item->GetItem()->IDFile[2]);
if (material==MaterialPrimary)
cs->primary[char_num]=idfile;
else
cs->secondary[char_num]=idfile;
}
}
}
/* Otherwise, use the zone and coordinates given */
else {
pp.binds[4].zoneId = (uint32)atoi(row_d[0]);
float x = atof(row_d[2]);
float y = atof(row_d[3]);
float z = atof(row_d[4]);
if (x == 0 && y == 0 && z == 0){ GetSafePoints(pp.binds[4].zoneId, 0, &x, &y, &z); }
pp.binds[4].x = x; pp.binds[4].y = y; pp.binds[4].z = z;
}
else
{
printf("Error loading inventory for %s\n", cs->name[char_num]);
}
safe_delete(inv);
if (++char_num > 10)
break;
}
else
{
std::cout << "Got a bogus character (" << row[0] << ") Ignoring!!!" << std::endl;
std::cout << "PP length ="<<lengths[1]<<" but PP should be "<<sizeof(PlayerProfile_Struct) << std::endl;
//DeleteCharacter(row[0]);
pp.binds[0] = pp.binds[4];
/* If no home bind set, set it */
if (has_home == 0){
std::string query = StringFormat("REPLACE INTO `character_bind` (id, zone_id, instance_id, x, y, z, heading, is_home)"
" VALUES (%u, %u, %u, %f, %f, %f, %f, %i)",
character_id, pp.binds[4].zoneId, 0, pp.binds[4].x, pp.binds[4].y, pp.binds[4].z, pp.binds[4].heading, 1);
auto results_bset = QueryDatabase(query); ThrowDBError(results_bset.ErrorMessage(), "WorldDatabase::GetCharSelectInfo Set Home Point", query);
}
/* If no regular bind set, set it */
if (has_bind == 0){
std::string query = StringFormat("REPLACE INTO `character_bind` (id, zone_id, instance_id, x, y, z, heading, is_home)"
" VALUES (%u, %u, %u, %f, %f, %f, %f, %i)",
character_id, pp.binds[0].zoneId, 0, pp.binds[0].x, pp.binds[0].y, pp.binds[0].z, pp.binds[0].heading, 0);
auto results_bset = QueryDatabase(query); ThrowDBError(results_bset.ErrorMessage(), "WorldDatabase::GetCharSelectInfo Set Bind Point", query);
}
}
mysql_free_result(result);
}
else
{
std::cerr << "Error in GetCharSelectInfo query '" << query << "' " << errbuf << std::endl;
safe_delete_array(query);
return;
/* Bind End */
/*
Character's equipped items
@merth: Haven't done bracer01/bracer02 yet.
Also: this needs a second look after items are a little more solid
NOTE: items don't have a color, players MAY have a tint, if the
use_tint part is set. otherwise use the regular color
*/
/* Load Character Material Data for Char Select */
cquery = StringFormat("SELECT slot, red, green, blue, use_tint, color FROM `character_material` WHERE `id` = %u", character_id);
auto results_b = database.QueryDatabase(cquery); uint8 slot = 0;
for (auto row_b = results_b.begin(); row_b != results_b.end(); ++row_b) {
slot = atoi(row_b[0]);
pp.item_tint[slot].rgb.red = atoi(row_b[1]);
pp.item_tint[slot].rgb.green = atoi(row_b[2]);
pp.item_tint[slot].rgb.blue = atoi(row_b[3]);
pp.item_tint[slot].rgb.use_tint = atoi(row_b[4]);
}
/* Load Inventory */
inv = new Inventory;
if (GetInventory(account_id, cs->name[char_num], inv)) {
for (uint8 material = 0; material <= 8; material++) {
uint32 color = 0;
ItemInst *item = inv->GetItem(Inventory::CalcSlotFromMaterial(material));
if (item == 0)
continue;
cs->equip[char_num][material] = item->GetItem()->Material;
if (pp.item_tint[material].rgb.use_tint){ color = pp.item_tint[material].color; }
else{ color = item->GetItem()->Color; }
cs->cs_colors[char_num][material].color = color;
/* Weapons are handled a bit differently */
if ((material == MaterialPrimary) || (material == MaterialSecondary)) {
if (strlen(item->GetItem()->IDFile) > 2) {
uint32 idfile = atoi(&item->GetItem()->IDFile[2]);
if (material == MaterialPrimary)
cs->primary[char_num] = idfile;
else
cs->secondary[char_num] = idfile;
}
}
}
}
else {
printf("Error loading inventory for %s\n", cs->name[char_num]);
}
safe_delete(inv);
if (++char_num > 10)
break;
}
return;
}
int WorldDatabase::MoveCharacterToBind(int CharID, uint8 bindnum) {
// if an invalid bind point is specified, use the primary bind
if (bindnum > 4)
bindnum = 0;
/* if an invalid bind point is specified, use the primary bind */
if (bindnum > 4){ bindnum = 0; }
int is_home = 0;
if (bindnum == 4){ is_home = 1; }
char errbuf[MYSQL_ERRMSG_SIZE];
char *query = 0;
MYSQL_RES *result;
MYSQL_ROW row;
uint32 affected_rows = 0;
PlayerProfile_Struct pp;
bool PPValid = false;
if (RunQuery(query, MakeAnyLenString(&query, "SELECT profile from character_ where id='%i'", CharID), errbuf, &result)) {
row = mysql_fetch_row(result);
unsigned long* lengths = mysql_fetch_lengths(result);
if (lengths[0] == sizeof(PlayerProfile_Struct)) {
memcpy(&pp, row[0], sizeof(PlayerProfile_Struct));
PPValid = true;
}
mysql_free_result(result);
std::string query = StringFormat("SELECT `zone_id` FROM `character_bind` WHERE `id` = %u AND `is_home` = %u LIMIT 1", CharID, is_home);
auto results = database.QueryDatabase(query); int i = 0;
for (auto row = results.begin(); row != results.end(); ++row) {
return atoi(row[0]);
}
safe_delete_array(query);
if(!PPValid) return 0;
const char *BindZoneName = StaticGetZoneName(pp.binds[bindnum].zoneId);
if(!strcmp(BindZoneName, "UNKNWN")) return pp.zone_id;
if (!RunQuery(query, MakeAnyLenString(&query, "UPDATE character_ SET zonename = '%s',zoneid=%i,x=%f, y=%f, z=%f, instanceid=0 WHERE id='%i'",
BindZoneName, pp.binds[bindnum].zoneId, pp.binds[bindnum].x, pp.binds[bindnum].y, pp.binds[bindnum].z,
CharID), errbuf, 0,&affected_rows)) {
return pp.zone_id;
}
safe_delete_array(query);
return pp.binds[bindnum].zoneId;
}
bool WorldDatabase::GetStartZone(PlayerProfile_Struct* in_pp, CharCreate_Struct* in_cc)
@@ -444,12 +391,16 @@ bool WorldDatabase::GetStartZoneSoF(PlayerProfile_Struct* in_pp, CharCreate_Stru
in_pp->x = in_pp->y = in_pp->z = in_pp->heading = in_pp->zone_id = 0;
in_pp->binds[0].x = in_pp->binds[0].y = in_pp->binds[0].z = in_pp->binds[0].zoneId = 0;
if(!RunQuery(query, MakeAnyLenString(&query, "SELECT x,y,z,heading,bind_id FROM start_zones WHERE zone_id=%i AND player_class=%i "
"AND player_deity=%i AND player_race=%i",
in_cc->start_zone,
in_cc->class_,
in_cc->deity,
in_cc->race), errbuf, &result))
if(!RunQuery(query, MakeAnyLenString(&query, "SELECT x, y, z, heading, bind_id "
" FROM start_zones "
" WHERE zone_id = %i "
" AND player_class = %i "
" AND player_deity = %i"
" AND player_race = %i",
in_cc->start_zone,
in_cc->class_,
in_cc->deity,
in_cc->race), errbuf, &result))
{
LogFile->write(EQEMuLog::Status, "SoF Start zone query failed: %s : %s\n", query, errbuf);
safe_delete_array(query);
@@ -532,7 +483,7 @@ void WorldDatabase::SetMailKey(int CharID, int IPAddress, int MailKey) {
else
sprintf(MailKeyString, "%08X", MailKey);
if (!RunQuery(query, MakeAnyLenString(&query, "UPDATE character_ SET mailkey = '%s' WHERE id='%i'",
if (!RunQuery(query, MakeAnyLenString(&query, "UPDATE `character_data` SET mailkey = '%s' WHERE id='%i'",
MailKeyString, CharID), errbuf))
LogFile->write(EQEMuLog::Error, "WorldDatabase::SetMailKey(%i, %s) : %s", CharID, MailKeyString, errbuf);
@@ -548,7 +499,7 @@ bool WorldDatabase::GetCharacterLevel(const char *name, int &level)
MYSQL_RES *result;
MYSQL_ROW row;
if(RunQuery(query, MakeAnyLenString(&query, "SELECT level FROM character_ WHERE name='%s'", name), errbuf, &result))
if(RunQuery(query, MakeAnyLenString(&query, "SELECT `level` FROM `character_data` WHERE `name` = '%s'", name), errbuf, &result))
{
if(row = mysql_fetch_row(result))
{
+1 -1
View File
@@ -31,7 +31,7 @@ public:
bool GetStartZone(PlayerProfile_Struct* in_pp, CharCreate_Struct* in_cc);
bool GetStartZoneSoF(PlayerProfile_Struct* in_pp, CharCreate_Struct* in_cc);
void GetCharSelectInfo(uint32 account_id, CharacterSelect_Struct*);
void GetCharSelectInfo(uint32 account_id, CharacterSelect_Struct*, uint32 ClientVersion);
int MoveCharacterToBind(int CharID, uint8 bindnum = 0);
void GetLauncherList(std::vector<std::string> &result);
+2 -2
View File
@@ -87,7 +87,7 @@ void ZSList::Process() {
CatchSignal(2);
}
if(reminder && reminder->Check()){
SendEmoteMessage(0,0,0,15,"<SYSTEMWIDE MESSAGE>:SYSTEM MSG:World coming down, everyone log out now. World will shut down in %i seconds...",shutdowntimer->GetRemainingTime()/1000);
SendEmoteMessage(0,0,0,15,"<SYSTEMWIDE MESSAGE>:SYSTEM MSG:World coming down, everyone log out now. World will shut down in %i minutes...", ((shutdowntimer->GetRemainingTime()/1000) / 60));
}
LinkedListIterator<ZoneServer*> iterator(list);
@@ -718,7 +718,7 @@ void ZSList::GetZoneIDList(std::vector<uint32> &zones) {
void ZSList::WorldShutDown(uint32 time, uint32 interval)
{
if( time > 0 ) {
SendEmoteMessage(0,0,0,15,"<SYSTEMWIDE MESSAGE>:SYSTEM MSG:World coming down in %i seconds, everyone log out before this time.",time);
SendEmoteMessage(0,0,0,15,"<SYSTEMWIDE MESSAGE>:SYSTEM MSG:World coming down in %i minutes, everyone log out before this time.", (time / 60));
time *= 1000;
interval *= 1000;
+38 -72
View File
@@ -655,17 +655,17 @@ bool ZoneServer::Process() {
client->Clearance(wtz->response);
}
case ServerOP_ZoneToZoneRequest: {
//
// solar: ZoneChange is received by the zone the player is in, then the
// zone sends a ZTZ which ends up here. This code then find the target
// (ingress point) and boots it if needed, then sends the ZTZ to it.
// The ingress server will decide wether the player can enter, then will
// send back the ZTZ to here. This packet is passed back to the egress
// server, which will send a ZoneChange response back to the client
// which can be an error, or a success, in which case the client will
// disconnect, and their zone location will be saved when ~Client is
// called, so it will be available when they ask to zone.
//
//
// solar: ZoneChange is received by the zone the player is in, then the
// zone sends a ZTZ which ends up here. This code then find the target
// (ingress point) and boots it if needed, then sends the ZTZ to it.
// The ingress server will decide wether the player can enter, then will
// send back the ZTZ to here. This packet is passed back to the egress
// server, which will send a ZoneChange response back to the client
// which can be an error, or a success, in which case the client will
// disconnect, and their zone location will be saved when ~Client is
// called, so it will be available when they ask to zone.
//
if(pack->size != sizeof(ZoneToZone_Struct))
@@ -678,40 +678,31 @@ bool ZoneServer::Process() {
zlog(WORLD__ZONE,"ZoneToZone request for %s current zone %d req zone %d\n",
ztz->name, ztz->current_zone_id, ztz->requested_zone_id);
if(GetZoneID() == ztz->current_zone_id && GetInstanceID() == ztz->current_instance_id) // this is a request from the egress zone
{
/* This is a request from the egress zone */
if(GetZoneID() == ztz->current_zone_id && GetInstanceID() == ztz->current_instance_id) {
zlog(WORLD__ZONE,"Processing ZTZ for egress from zone for client %s\n", ztz->name);
if
(
ztz->admin < 80 &&
ztz->ignorerestrictions < 2 &&
zoneserver_list.IsZoneLocked(ztz->requested_zone_id)
)
{
if (ztz->admin < 80 && ztz->ignorerestrictions < 2 && zoneserver_list.IsZoneLocked(ztz->requested_zone_id)) {
ztz->response = 0;
SendPacket(pack);
break;
}
ZoneServer *ingress_server = nullptr;
if(ztz->requested_instance_id > 0)
{
if(ztz->requested_instance_id > 0) {
ingress_server = zoneserver_list.FindByInstanceID(ztz->requested_instance_id);
}
else
{
ingress_server = zoneserver_list.FindByZoneID(ztz->requested_zone_id);
else {
ingress_server = zoneserver_list.FindByZoneID(ztz->requested_zone_id);
}
if(ingress_server) // found a zone already running
{
/* Zone was already running*/
if(ingress_server) {
_log(WORLD__ZONE,"Found a zone already booted for %s\n", ztz->name);
ztz->response = 1;
}
else // need to boot one
{
/* Boot the Zone*/
else {
int server_id;
if ((server_id = zoneserver_list.TriggerBootup(ztz->requested_zone_id, ztz->requested_instance_id))){
_log(WORLD__ZONE,"Successfully booted a zone for %s\n", ztz->name);
@@ -719,8 +710,7 @@ bool ZoneServer::Process() {
ztz->response = 1;
ingress_server = zoneserver_list.FindByID(server_id);
}
else
{
else {
_log(WORLD__ZONE_ERR,"FAILED to boot a zone for %s\n", ztz->name);
// bootup failed, send back error code 0
ztz->response = 0;
@@ -728,27 +718,24 @@ bool ZoneServer::Process() {
}
if(ztz->response!=0 && client)
client->LSZoneChange(ztz);
SendPacket(pack); // send back to egress server
if(ingress_server) // if we couldn't boot one, this is 0
{
ingress_server->SendPacket(pack); // inform target server
}
SendPacket(pack); // send back to egress server
if(ingress_server) {
ingress_server->SendPacket(pack); // inform target server
}
}
else // this is response from the ingress server, route it back to the egress server
{
/* Response from Ingress server, route back to egress */
else{
zlog(WORLD__ZONE,"Processing ZTZ for ingress to zone for client %s\n", ztz->name);
ZoneServer *egress_server = nullptr;
if(ztz->current_instance_id > 0)
{
if(ztz->current_instance_id > 0) {
egress_server = zoneserver_list.FindByInstanceID(ztz->current_instance_id);
}
else
{
else {
egress_server = zoneserver_list.FindByZoneID(ztz->current_zone_id);
}
if(egress_server)
{
if(egress_server) {
egress_server->SendPacket(pack);
}
}
@@ -786,21 +773,18 @@ bool ZoneServer::Process() {
delete whom;
break;
}
case ServerOP_RequestOnlineGuildMembers:
{
case ServerOP_RequestOnlineGuildMembers: {
ServerRequestOnlineGuildMembers_Struct *srogms = (ServerRequestOnlineGuildMembers_Struct*) pack->pBuffer;
zlog(GUILDS__IN_PACKETS, "ServerOP_RequestOnlineGuildMembers Recieved. FromID=%i GuildID=%i", srogms->FromID, srogms->GuildID);
client_list.SendOnlineGuildMembers(srogms->FromID, srogms->GuildID);
break;
}
case ServerOP_ClientVersionSummary:
{
case ServerOP_ClientVersionSummary: {
ServerRequestClientVersionSummary_Struct *srcvss = (ServerRequestClientVersionSummary_Struct*) pack->pBuffer;
client_list.SendClientVersionSummary(srcvss->Name);
break;
}
case ServerOP_ReloadRules:
{
case ServerOP_ReloadRules: {
zoneserver_list.SendPacket(pack);
RuleManager::Instance()->LoadRules(&database, "default");
break;
@@ -1275,37 +1259,19 @@ bool ZoneServer::Process() {
case ServerOP_QueryServGeneric:
case ServerOP_Speech:
case ServerOP_QSPlayerLogTrades:
{
QSLink.SendPacket(pack);
break;
}
case ServerOP_QSPlayerLogHandins:
{
QSLink.SendPacket(pack);
break;
}
case ServerOP_QSPlayerLogNPCKills:
{
QSLink.SendPacket(pack);
break;
}
case ServerOP_QSPlayerLogDeletes:
{
QSLink.SendPacket(pack);
break;
}
case ServerOP_QSPlayerLogMoves:
{
QSLink.SendPacket(pack);
break;
}
case ServerOP_QSPlayerLogMerchantTransactions:
{
QSLink.SendPacket(pack);
break;
}
case ServerOP_CZSignalClientByName:
case ServerOP_CZMessagePlayer:
case ServerOP_CZMessagePlayer:
case ServerOP_CZSignalNPC:
case ServerOP_CZSetEntityVariableByNPCTypeID:
case ServerOP_CZSignalClient:
{
zoneserver_list.SendPacket(pack);
-2
View File
@@ -119,7 +119,6 @@ SET(zone_sources
zone_logsys.cpp
zone_config.cpp
zonedb.cpp
zonedbasync.cpp
zoning.cpp
)
@@ -207,7 +206,6 @@ SET(zone_headers
zone.h
zone_config.h
zonedb.h
zonedbasync.h
zonedump.h
)
+29 -14
View File
@@ -18,6 +18,8 @@ Copyright (C) 2001-2004 EQEMu Development Team (http://eqemulator.net)
// Test 1
#include <iostream>
#include "../common/debug.h"
#include "aa.h"
#include "mob.h"
@@ -300,7 +302,7 @@ void Client::ActivateAA(aaID activate){
return;
}
} else {
if(!CastSpell(caa->spell_id, target_id, 10, -1, -1, 0, -1, AATimerID + pTimerAAStart, timer_base, 1)) {
if (!CastSpell(caa->spell_id, target_id, USE_ITEM_SPELL_SLOT, -1, -1, 0, -1, AATimerID + pTimerAAStart, timer_base, 1)) {
//Reset on failed cast
SendAATimer(AATimerID, 0, 0xFFFFFF);
Message_StringID(15,ABILITY_FAILED);
@@ -316,13 +318,14 @@ void Client::ActivateAA(aaID activate){
}
}
// Check if AA is expendable
if (aas_send[activate - activate_val]->special_category == 7)
{
if (aas_send[activate - activate_val]->special_category == 7) {
// Add the AA cost to the extended profile to track overall total
m_epp.expended_aa += aas_send[activate]->cost;
SetAA(activate, 0);
Save();
SaveAA(); /* Save Character AA */
SendAA(activate);
SendAATable();
}
@@ -525,7 +528,7 @@ void Client::HandleAAAction(aaID activate) {
//cast the spell, if we have one
if(IsValidSpell(spell_id)) {
int aatid = GetAATimerID(activate);
if(!CastSpell(spell_id, target_id , 10, -1, -1, 0, -1, pTimerAAStart + aatid , CalcAAReuseTimer(caa), 1)) {
if (!CastSpell(spell_id, target_id, USE_ITEM_SPELL_SLOT, -1, -1, 0, -1, pTimerAAStart + aatid, CalcAAReuseTimer(caa), 1)) {
SendAATimer(aatid, 0, 0xFFFFFF);
Message_StringID(15,ABILITY_FAILED);
p_timers.Clear(&database, pTimerAAStart + aatid);
@@ -1035,8 +1038,7 @@ void Client::BuyAA(AA_Action* action)
uint32 real_cost;
std::map<uint32, AALevelCost_Struct>::iterator RequiredLevel = AARequiredLevelAndCost.find(action->ability);
if(RequiredLevel != AARequiredLevelAndCost.end())
{
if(RequiredLevel != AARequiredLevelAndCost.end()) {
real_cost = RequiredLevel->second.Cost;
}
else
@@ -1049,7 +1051,11 @@ void Client::BuyAA(AA_Action* action)
m_pp.aapoints -= real_cost;
Save();
/* Do Player Profile rank calculations and set player profile */
SaveAA();
/* Save to Database to avoid having to write the whole AA array to the profile, only write changes*/
// database.SaveCharacterAA(this->CharacterID(), aa2->id, (cur_level + 1));
if ((RuleB(AA, Stacking) && (GetClientVersionBit() >= 4) && (aa2->hotkey_sid == 4294967295u))
&& ((aa2->max_level == (cur_level + 1)) && aa2->sof_next_id)){
SendAA(aa2->id);
@@ -1060,8 +1066,10 @@ void Client::BuyAA(AA_Action* action)
SendAATable();
//we are building these messages ourself instead of using the stringID to work around patch discrepencies
//these are AA_GAIN_ABILITY (410) & AA_IMPROVE (411), respectively, in both Titanium & SoF. not sure about 6.2
/*
We are building these messages ourself instead of using the stringID to work around patch discrepencies
these are AA_GAIN_ABILITY (410) & AA_IMPROVE (411), respectively, in both Titanium & SoF. not sure about 6.2
*/
/* Initial purchase of an AA ability */
if (cur_level < 1){
@@ -1084,8 +1092,6 @@ void Client::BuyAA(AA_Action* action)
}
}
SendAAStats();
CalcBonuses();
@@ -1514,11 +1520,15 @@ bool ZoneDatabase::LoadAAEffects2() {
return true;
}
void Client::ResetAA(){
RefundAA();
uint32 i;
for(i=0;i<MAX_PP_AA_ARRAY;i++){
aa[i]->AA = 0;
aa[i]->value = 0;
m_pp.aa_array[MAX_PP_AA_ARRAY].AA = 0;
m_pp.aa_array[MAX_PP_AA_ARRAY].value = 0;
}
std::map<uint32,uint8>::iterator itr;
for(itr=aa_points.begin();itr!=aa_points.end();++itr)
aa_points[itr->first] = 0;
@@ -1530,6 +1540,12 @@ void Client::ResetAA(){
m_pp.raid_leadership_points = 0;
m_pp.group_leadership_exp = 0;
m_pp.raid_leadership_exp = 0;
database.DeleteCharacterAAs(this->CharacterID());
SaveAA();
SendAATable();
database.DeleteCharacterLeadershipAAs(this->CharacterID());
Kick();
}
int Client::GroupLeadershipAAHealthEnhancement()
@@ -1818,8 +1834,7 @@ void ZoneDatabase::LoadAAs(SendAA_Struct **load){
}
AALevelCost_Struct aalcs;
for (auto row = results.begin(); row != results.end(); ++row)
{
for (auto row = results.begin(); row != results.end(); ++row) {
aalcs.Level = atoi(row[1]);
aalcs.Cost = atoi(row[2]);
AARequiredLevelAndCost[atoi(row[0])] = aalcs;
+55 -26
View File
@@ -3331,10 +3331,13 @@ int32 Mob::ReduceAllDamage(int32 damage)
if(damage <= 0)
return damage;
if(spellbonuses.ManaAbsorbPercentDamage[0] && (GetMana() > damage * spellbonuses.ManaAbsorbPercentDamage[0] / 100)) {
damage -= (damage * spellbonuses.ManaAbsorbPercentDamage[0] / 100);
SetMana(GetMana() - damage);
TryTriggerOnValueAmount(false, true);
if(spellbonuses.ManaAbsorbPercentDamage[0]) {
int32 mana_reduced = damage * spellbonuses.ManaAbsorbPercentDamage[0] / 100;
if (GetMana() >= mana_reduced){
damage -= mana_reduced;
SetMana(GetMana() - mana_reduced);
TryTriggerOnValueAmount(false, true);
}
}
CheckNumHitsRemaining(NUMHIT_IncomingDamage);
@@ -4804,6 +4807,26 @@ void Mob::CommonBreakInvisible()
improved_hidden = false;
}
/* Dev quotes:
* Old formula
* Final delay = (Original Delay / (haste mod *.01f)) + ((Hundred Hands / 100) * Original Delay)
* New formula
* Final delay = (Original Delay / (haste mod *.01f)) + ((Hundred Hands / 1000) * (Original Delay / (haste mod *.01f))
* Base Delay 20 25 30 37
* Haste 2.25 2.25 2.25 2.25
* HHE (old) -17 -17 -17 -17
* Final Delay 5.488888889 6.861111111 8.233333333 10.15444444
*
* Base Delay 20 25 30 37
* Haste 2.25 2.25 2.25 2.25
* HHE (new) -383 -383 -383 -383
* Final Delay 5.484444444 6.855555556 8.226666667 10.14622222
*
* Difference -0.004444444 -0.005555556 -0.006666667 -0.008222222
*
* These times are in 10th of a second
*/
void Mob::SetAttackTimer()
{
attack_timer.SetAtTrigger(4000, true);
@@ -4811,7 +4834,7 @@ void Mob::SetAttackTimer()
void Client::SetAttackTimer()
{
float PermaHaste = GetPermaHaste();
float haste_mod = GetHaste() * 0.01f;
//default value for attack timer in case they have
//an invalid weapon equipped:
@@ -4876,28 +4899,30 @@ void Client::SetAttackTimer()
}
}
int16 DelayMod = std::max(itembonuses.HundredHands + spellbonuses.HundredHands, -99);
int hhe = itembonuses.HundredHands + spellbonuses.HundredHands;
int speed = 0;
int delay = 36;
float quiver_haste = 0.0f;
//if we have no weapon..
if (ItemToUse == nullptr) {
//above checks ensure ranged weapons do not fall into here
// Work out if we're a monk
if ((GetClass() == MONK) || (GetClass() == BEASTLORD))
speed = static_cast<int>((GetMonkHandToHandDelay() * (100 + DelayMod) / 100) * PermaHaste);
else
speed = static_cast<int>((36 * (100 + DelayMod) / 100) * PermaHaste);
if (GetClass() == MONK || GetClass() == BEASTLORD)
delay = GetMonkHandToHandDelay();
} else {
//we have a weapon, use its delay
// Convert weapon delay to timer resolution (milliseconds)
//delay * 100
speed = static_cast<int>((ItemToUse->Delay * (100 + DelayMod) / 100) * PermaHaste);
if (ItemToUse->ItemType == ItemTypeBow || ItemToUse->ItemType == ItemTypeLargeThrowing) {
float quiver_haste = GetQuiverHaste();
if (quiver_haste > 0)
speed *= quiver_haste;
}
delay = ItemToUse->Delay;
if (ItemToUse->ItemType == ItemTypeBow || ItemToUse->ItemType == ItemTypeLargeThrowing)
quiver_haste = GetQuiverHaste();
}
if (RuleB(Spells, Jun182014HundredHandsRevamp))
speed = static_cast<int>(((delay / haste_mod) + ((hhe / 1000.0f) * (delay / haste_mod))) * 100);
else
speed = static_cast<int>(((delay / haste_mod) + ((hhe / 100.0f) * delay)) * 100);
// this is probably wrong
if (quiver_haste > 0)
speed *= quiver_haste;
TimerToUse->SetAtTrigger(std::max(RuleI(Combat, MinHastedDelay), speed), true);
if (i == MainPrimary)
@@ -4907,13 +4932,24 @@ void Client::SetAttackTimer()
void NPC::SetAttackTimer()
{
float PermaHaste = GetPermaHaste();
float haste_mod = GetHaste() * 0.01f;
//default value for attack timer in case they have
//an invalid weapon equipped:
attack_timer.SetAtTrigger(4000, true);
Timer *TimerToUse = nullptr;
int hhe = itembonuses.HundredHands + spellbonuses.HundredHands;
// Technically NPCs should do some logic for weapons, but the effect is minimal
// What they do is take the lower of their set delay and the weapon's
// ex. Mob's delay set to 20, weapon set to 19, delay 19
// Mob's delay set to 20, weapon set to 21, delay 20
int speed = 0;
if (RuleB(Spells, Jun182014HundredHandsRevamp))
speed = static_cast<int>(((attack_delay / haste_mod) + ((hhe / 1000.0f) * (attack_delay / haste_mod))) * 100);
else
speed = static_cast<int>(((attack_delay / haste_mod) + ((hhe / 100.0f) * attack_delay)) * 100);
for (int i = MainRange; i <= MainSecondary; i++) {
//pick a timer
@@ -4935,13 +4971,6 @@ void NPC::SetAttackTimer()
}
}
int16 DelayMod = std::max(itembonuses.HundredHands + spellbonuses.HundredHands, -99);
// Technically NPCs should do some logic for weapons, but the effect is minimal
// What they do is take the lower of their set delay and the weapon's
// ex. Mob's delay set to 20, weapon set to 19, delay 19
// Mob's delay set to 20, weapon set to 21, delay 20
int speed = static_cast<int>((attack_delay * (100 + DelayMod) / 100) * PermaHaste);
TimerToUse->SetAtTrigger(std::max(RuleI(Combat, MinHastedDelay), speed), true);
}
}
+17 -4
View File
@@ -104,6 +104,8 @@ void Client::CalcBonuses()
CalcMaxMana();
CalcMaxEndurance();
SetAttackTimer();
rooted = FindType(SE_Root);
XPRate = 100 + spellbonuses.XPRateMod;
@@ -174,8 +176,6 @@ void Client::CalcItemBonuses(StatBonuses* newbon) {
if(newbon->EnduranceRegen > CalcEnduranceRegenCap())
newbon->EnduranceRegen = CalcEnduranceRegenCap();
SetAttackTimer();
}
void Client::AddItemBonuses(const ItemInst *inst, StatBonuses* newbon, bool isAug, bool isTribute) {
@@ -1546,6 +1546,11 @@ void Mob::ApplySpellsBonuses(uint16 spell_id, uint8 casterlevel, StatBonuses* ne
case SE_AttackSpeed4:
{
// These don't generate the IMMUNE_ATKSPEED message and the icon shows up
// but have no effect on the mobs attack speed
if (GetSpecialAbility(UNSLOWABLE))
break;
if (effect_value < 0) //A few spells use negative values(Descriptions all indicate it should be a slow)
effect_value = effect_value * -1;
@@ -2467,7 +2472,7 @@ void Mob::ApplySpellsBonuses(uint16 spell_id, uint8 casterlevel, StatBonuses* ne
}
break;
}
case SE_ManaAbsorbPercentDamage:
{
if (newbon->ManaAbsorbPercentDamage[0] < effect_value){
@@ -2488,7 +2493,7 @@ void Mob::ApplySpellsBonuses(uint16 spell_id, uint8 casterlevel, StatBonuses* ne
case SE_ShieldBlock:
newbon->ShieldBlock += effect_value;
break;
case SE_ShieldEquipHateMod:
newbon->ShieldEquipHateMod += effect_value;
break;
@@ -2502,6 +2507,10 @@ void Mob::ApplySpellsBonuses(uint16 spell_id, uint8 casterlevel, StatBonuses* ne
newbon->BlockBehind += effect_value;
break;
case SE_Blind:
newbon->IsBlind = true;
break;
case SE_Fear:
newbon->IsFeared = true;
break;
@@ -4081,6 +4090,10 @@ void Mob::NegateSpellsBonuses(uint16 spell_id)
itembonuses.BlockBehind = effect_value;
break;
case SE_Blind:
spellbonuses.IsBlind = false;
break;
case SE_Fear:
spellbonuses.IsFeared = false;
break;
+891 -1300
View File
File diff suppressed because it is too large Load Diff
+2 -2
View File
@@ -311,11 +311,11 @@ public:
virtual float GetAOERange(uint16 spell_id);
virtual bool SpellEffect(Mob* caster, uint16 spell_id, float partial = 100);
virtual void DoBuffTic(uint16 spell_id, int slot, uint32 ticsremaining, uint8 caster_level, Mob* caster = 0);
virtual bool CastSpell(uint16 spell_id, uint16 target_id, uint16 slot = 10, int32 casttime = -1, int32 mana_cost = -1, uint32* oSpellWillFinish = 0, uint32 item_slot = 0xFFFFFFFF, int16 *resist_adjust = nullptr);
virtual bool CastSpell(uint16 spell_id, uint16 target_id, uint16 slot = USE_ITEM_SPELL_SLOT, int32 casttime = -1, int32 mana_cost = -1, uint32* oSpellWillFinish = 0, uint32 item_slot = 0xFFFFFFFF, int16 *resist_adjust = nullptr);
virtual bool SpellOnTarget(uint16 spell_id, Mob* spelltar);
virtual bool IsImmuneToSpell(uint16 spell_id, Mob *caster);
virtual bool DetermineSpellTargets(uint16 spell_id, Mob *&spell_target, Mob *&ae_center, CastAction_type &CastAction);
virtual bool DoCastSpell(uint16 spell_id, uint16 target_id, uint16 slot = 10, int32 casttime = -1, int32 mana_cost = -1, uint32* oSpellWillFinish = 0, uint32 item_slot = 0xFFFFFFFF);
virtual bool DoCastSpell(uint16 spell_id, uint16 target_id, uint16 slot = USE_ITEM_SPELL_SLOT, int32 casttime = -1, int32 mana_cost = -1, uint32* oSpellWillFinish = 0, uint32 item_slot = 0xFFFFFFFF);
// Bot Action Command Methods
bool MesmerizeTarget(Mob* target);
+131 -157
View File
@@ -73,8 +73,6 @@ extern uint32 numclients;
extern PetitionList petition_list;
bool commandlogged;
char entirecommand[255];
extern DBAsyncFinishedQueue MTdbafq;
extern DBAsync *dbasync;
Client::Client(EQStreamInterface* ieqs)
: Mob("No name", // name
@@ -479,60 +477,23 @@ void Client::ReportConnectingState() {
};
}
bool Client::Save(uint8 iCommitNow) {
#if 0
// Orig. Offset: 344 / 0x00000000
// Length: 36 / 0x00000024
unsigned char rawData[36] =
{
0x0D, 0x30, 0xE1, 0x30, 0x1E, 0x10, 0x22, 0x10, 0x20, 0x10, 0x21, 0x10, 0x1C, 0x20, 0x1F, 0x10,
0x7C, 0x10, 0x68, 0x10, 0x51, 0x10, 0x78, 0x10, 0xBD, 0x10, 0xD2, 0x10, 0xCD, 0x10, 0xD1, 0x10,
0x01, 0x10, 0x6D, 0x10
} ;
for (int tmp = 0;tmp <=35;tmp++){
m_pp.unknown0256[89+tmp] = rawData[tmp];
}
#endif
if(!ClientDataLoaded())
return false;
m_pp.x = x_pos;
m_pp.y = y_pos;
m_pp.z = z_pos;
m_pp.guildrank=guildrank;
m_pp.heading = heading;
// Temp Hack for signed values until we get the root of the problem changed over to signed...
if (m_pp.copper < 0) { m_pp.copper = 0; }
if (m_pp.silver < 0) { m_pp.silver = 0; }
if (m_pp.gold < 0) { m_pp.gold = 0; }
if (m_pp.platinum < 0) { m_pp.platinum = 0; }
if (m_pp.copper_bank < 0) { m_pp.copper_bank = 0; }
if (m_pp.silver_bank < 0) { m_pp.silver_bank = 0; }
if (m_pp.gold_bank < 0) { m_pp.gold_bank = 0; }
if (m_pp.platinum_bank < 0) { m_pp.platinum_bank = 0; }
int spentpoints=0;
for(int a=0;a < MAX_PP_AA_ARRAY;a++) {
bool Client::SaveAA(){
int first_entry = 0;
std::string rquery;
/* Save Player AA */
int spentpoints = 0;
for (int a = 0; a < MAX_PP_AA_ARRAY; a++) {
uint32 points = aa[a]->value;
if(points > HIGHEST_AA_VALUE) // Unifying this
{
if (points > HIGHEST_AA_VALUE) {
aa[a]->value = HIGHEST_AA_VALUE;
points = HIGHEST_AA_VALUE;
}
if (points > 0)
{
SendAA_Struct* curAA = zone->FindAA(aa[a]->AA-aa[a]->value+1);
if(curAA)
{
for (int rank=0; rank<points; rank++)
{
std::map<uint32, AALevelCost_Struct>::iterator RequiredLevel = AARequiredLevelAndCost.find(aa[a]->AA-aa[a]->value + 1 + rank);
if(RequiredLevel != AARequiredLevelAndCost.end())
{
if (points > 0) {
SendAA_Struct* curAA = zone->FindAA(aa[a]->AA - aa[a]->value + 1);
if (curAA) {
for (int rank = 0; rank<points; rank++) {
std::map<uint32, AALevelCost_Struct>::iterator RequiredLevel = AARequiredLevelAndCost.find(aa[a]->AA - aa[a]->value + 1 + rank);
if (RequiredLevel != AARequiredLevelAndCost.end()) {
spentpoints += RequiredLevel->second.Cost;
}
else
@@ -541,42 +502,72 @@ bool Client::Save(uint8 iCommitNow) {
}
}
}
m_pp.aapoints_spent = spentpoints + m_epp.expended_aa;
for (int a = 0; a < MAX_PP_AA_ARRAY; a++) {
if (aa[a]->AA > 0 && aa[a]->value){
if (first_entry != 1){
rquery = StringFormat("REPLACE INTO `character_alternate_abilities` (id, slot, aa_id, aa_value)"
" VALUES (%u, %u, %u, %u)", character_id, a, aa[a]->AA, aa[a]->value);
first_entry = 1;
}
rquery = rquery + StringFormat(", (%u, %u, %u, %u)", character_id, a, aa[a]->AA, aa[a]->value);
}
}
auto results = database.QueryDatabase(rquery);
return true;
}
bool Client::Save(uint8 iCommitNow) {
if(!ClientDataLoaded())
return false;
/* Wrote current basics to PP for saves */
m_pp.x = x_pos;
m_pp.y = y_pos;
m_pp.z = z_pos;
m_pp.guildrank = guildrank;
m_pp.heading = heading;
/* Mana and HP */
if (GetHP() <= 0) {
m_pp.cur_hp = GetMaxHP();
}
else
else {
m_pp.cur_hp = GetHP();
}
m_pp.mana = cur_mana;
m_pp.endurance = cur_end;
/* Save Character Currency */
database.SaveCharacterCurrency(this->CharacterID(), &m_pp);
/* Save Current Bind Points : Sets Instance to 0 because it is currently not implemented */
database.SaveCharacterBindPoint(this->CharacterID(), m_pp.binds[0].zoneId, 0, m_pp.binds[0].x, m_pp.binds[0].y, m_pp.binds[0].z, 0, 0); /* Regular bind */
database.SaveCharacterBindPoint(this->CharacterID(), m_pp.binds[4].zoneId, 0, m_pp.binds[4].x, m_pp.binds[4].y, m_pp.binds[4].z, 0, 1); /* Home Bind */
/* Save Character Buffs */
database.SaveBuffs(this);
/* Total Time Played */
TotalSecondsPlayed += (time(nullptr) - m_pp.lastlogin);
m_pp.timePlayedMin = (TotalSecondsPlayed / 60);
m_pp.RestTimer = rest_timer.GetRemainingTime() / 1000;
if(GetMercInfo().MercTimerRemaining > RuleI(Mercs, UpkeepIntervalMS))
/* Save Mercs */
if (GetMercInfo().MercTimerRemaining > RuleI(Mercs, UpkeepIntervalMS)) {
GetMercInfo().MercTimerRemaining = RuleI(Mercs, UpkeepIntervalMS);
}
if(GetMercTimer()->Enabled()) {
if (GetMercTimer()->Enabled()) {
GetMercInfo().MercTimerRemaining = GetMercTimer()->GetRemainingTime();
}
if (GetMerc() && !dead) {
} else {
if (!(GetMerc() && !dead)) {
memset(&m_mercinfo, 0, sizeof(struct MercInfo));
}
m_pp.lastlogin = time(nullptr);
if (pQueuedSaveWorkID) {
dbasync->CancelWork(pQueuedSaveWorkID);
pQueuedSaveWorkID = 0;
}
if (GetPet() && !GetPet()->IsFamiliar() && GetPet()->CastToNPC()->GetPetSpellID() && !dead) {
NPC *pet = GetPet()->CastToNPC();
@@ -591,58 +582,37 @@ bool Client::Save(uint8 iCommitNow) {
}
database.SavePetInfo(this);
if(tribute_timer.Enabled()) {
if(tribute_timer.Enabled()) {
m_pp.tribute_time_remaining = tribute_timer.GetRemainingTime();
} else {
m_pp.tribute_time_remaining = 0xFFFFFFFF;
m_pp.tribute_active = 0;
}
else {
m_pp.tribute_time_remaining = 0xFFFFFFFF; m_pp.tribute_active = 0;
}
p_timers.Store(&database);
// printf("Dumping inventory on save:\n");
// m_inv.dumpEntireInventory();
database.SaveCharacterTribute(this->CharacterID(), &m_pp);
SaveTaskState(); /* Save Character Task */
SaveTaskState();
if (iCommitNow <= 1) {
char* query = 0;
uint32_breakdown workpt;
workpt.b4() = DBA_b4_Entity;
workpt.w2_3() = GetID();
workpt.b1() = DBA_b1_Entity_Client_Save;
DBAsyncWork* dbaw = new DBAsyncWork(&database, &MTdbafq, workpt, DBAsync::Write, 0xFFFFFFFF);
dbaw->AddQuery(iCommitNow == 0 ? true : false, &query, database.SetPlayerProfile_MQ(&query, account_id, character_id, &m_pp, &m_inv, &m_epp, 0, 0, MaxXTargets), false);
if (iCommitNow == 0){
pQueuedSaveWorkID = dbasync->AddWork(&dbaw, 2500);
}
else {
dbasync->AddWork(&dbaw, 0);
SaveBackup();
}
safe_delete_array(query);
return true;
if(m_pp.hunger_level < 0) {
m_pp.hunger_level = 0;
}
else if (database.SetPlayerProfile(account_id, character_id, &m_pp, &m_inv, &m_epp, 0, 0, MaxXTargets)) {
SaveBackup();
}
else {
std::cerr << "Failed to update player profile" << std::endl;
return false;
else if(m_pp.hunger_level > 6000) {
m_pp.hunger_level = 6000;
}
/* Mirror Character Data */
database.StoreCharacterLookup(this->CharacterID());
if(m_pp.thirst_level < 0) {
m_pp.thirst_level = 0;
}
else if(m_pp.thirst_level > 6000) {
m_pp.thirst_level = 6000;
}
database.SaveCharacterData(this->CharacterID(), this->AccountID(), &m_pp, &m_epp); /* Save Character Data */
return true;
}
void Client::SaveBackup() {
if (!RunLoops)
return;
char* query = 0;
DBAsyncWork* dbaw = new DBAsyncWork(&database, &DBAsyncCB_CharacterBackup, this->CharacterID(), DBAsync::Read);
dbaw->AddQuery(0, &query, MakeAnyLenString(&query, "Select id, UNIX_TIMESTAMP()-UNIX_TIMESTAMP(ts) as age from character_backup where charid=%u and backupreason=0 order by ts asc", this->CharacterID()), true);
dbasync->AddWork(&dbaw, 0);
}
CLIENTPACKET::CLIENTPACKET()
@@ -731,14 +701,10 @@ void Client::QueuePacket(const EQApplicationPacket* app, bool ack_req, CLIENT_CO
}
void Client::FastQueuePacket(EQApplicationPacket** app, bool ack_req, CLIENT_CONN_STATUS required_state) {
//std::cout << "Sending: 0x" << std::hex << std::setw(4) << std::setfill('0') << (*app)->GetOpcode() << std::dec << ", size=" << (*app)->size << std::endl;
// if the program doesnt care about the status or if the status isnt what we requested
if (required_state != CLIENT_CONNECTINGALL && client_state != required_state) {
// todo: save packets for later use
AddPacket(app, ack_req);
// LogFile->write(EQEMuLog::Normal, "Adding Packet to list (%d) (%d)", (*app)->GetOpcode(), (int)required_state);
return;
}
else {
@@ -1406,12 +1372,14 @@ bool Client::UpdateLDoNPoints(int32 points, uint32 theme)
void Client::SetSkill(SkillUseTypes skillid, uint16 value) {
if (skillid > HIGHEST_SKILL)
return;
m_pp.skills[skillid] = value; // We need to be able to #setskill 254 and 255 to reset skills
return;
m_pp.skills[skillid] = value; // We need to be able to #setskill 254 and 255 to reset skills
database.SaveCharacterSkill(this->CharacterID(), skillid, value);
EQApplicationPacket* outapp = new EQApplicationPacket(OP_SkillUpdate, sizeof(SkillUpdate_Struct));
SkillUpdate_Struct* skill = (SkillUpdate_Struct*)outapp->pBuffer;
skill->skillId=skillid;
skill->skillId=skillid;
skill->value=value;
QueuePacket(outapp);
safe_delete(outapp);
@@ -1427,10 +1395,12 @@ void Client::IncreaseLanguageSkill(int skill_id, int value) {
if (m_pp.languages[skill_id] > 100) //Lang skill above max
m_pp.languages[skill_id] = 100;
database.SaveCharacterLanguage(this->CharacterID(), skill_id, m_pp.languages[skill_id]);
EQApplicationPacket* outapp = new EQApplicationPacket(OP_SkillUpdate, sizeof(SkillUpdate_Struct));
SkillUpdate_Struct* skill = (SkillUpdate_Struct*)outapp->pBuffer;
skill->skillId = 100 + skill_id;
skill->value = m_pp.languages[skill_id];
skill->value = m_pp.languages[skill_id];
QueuePacket(outapp);
safe_delete(outapp);
@@ -2115,7 +2085,7 @@ bool Client::TakeMoneyFromPP(uint64 copper, bool updateclient) {
m_pp.copper = copperpp;
if(updateclient)
SendMoneyUpdate();
Save();
SaveCurrency();
return true;
}
silver -= copper;
@@ -2130,7 +2100,7 @@ bool Client::TakeMoneyFromPP(uint64 copper, bool updateclient) {
m_pp.copper += (silver-(m_pp.silver*10));
if(updateclient)
SendMoneyUpdate();
Save();
SaveCurrency();
return true;
}
@@ -2150,7 +2120,7 @@ bool Client::TakeMoneyFromPP(uint64 copper, bool updateclient) {
m_pp.copper += coppertest;
if(updateclient)
SendMoneyUpdate();
Save();
SaveCurrency();
return true;
}
@@ -2168,7 +2138,7 @@ bool Client::TakeMoneyFromPP(uint64 copper, bool updateclient) {
if(updateclient)
SendMoneyUpdate();
RecalcWeight();
Save();
SaveCurrency();
return true;
}
}
@@ -2178,32 +2148,27 @@ void Client::AddMoneyToPP(uint64 copper, bool updateclient){
uint64 tmp2;
tmp = copper;
// Add Amount of Platinum
/* Add Amount of Platinum */
tmp2 = tmp/1000;
int32 new_val = m_pp.platinum + tmp2;
if(new_val < 0) {
m_pp.platinum = 0;
} else {
m_pp.platinum = m_pp.platinum + tmp2;
}
if(new_val < 0) { m_pp.platinum = 0; }
else { m_pp.platinum = m_pp.platinum + tmp2; }
tmp-=tmp2*1000;
//if (updateclient)
// SendClientMoneyUpdate(3,tmp2);
// Add Amount of Gold
/* Add Amount of Gold */
tmp2 = tmp/100;
new_val = m_pp.gold + tmp2;
if(new_val < 0) {
m_pp.gold = 0;
} else {
m_pp.gold = m_pp.gold + tmp2;
}
if(new_val < 0) { m_pp.gold = 0; }
else { m_pp.gold = m_pp.gold + tmp2; }
tmp-=tmp2*100;
//if (updateclient)
// SendClientMoneyUpdate(2,tmp2);
// Add Amount of Silver
/* Add Amount of Silver */
tmp2 = tmp/10;
new_val = m_pp.silver + tmp2;
if(new_val < 0) {
@@ -2234,13 +2199,12 @@ void Client::AddMoneyToPP(uint64 copper, bool updateclient){
RecalcWeight();
Save();
SaveCurrency();
LogFile->write(EQEMuLog::Debug, "Client::AddMoneyToPP() %s should have: plat:%i gold:%i silver:%i copper:%i", GetName(), m_pp.platinum, m_pp.gold, m_pp.silver, m_pp.copper);
}
void Client::AddMoneyToPP(uint32 copper, uint32 silver, uint32 gold, uint32 platinum, bool updateclient){
void Client::EVENT_ITEM_ScriptStopReturn(){
/* Set a timestamp in an entity variable for plugin check_handin.pl in return_items
This will stopgap players from items being returned if global_npc.pl has a catch all return_items
*/
@@ -2249,6 +2213,10 @@ void Client::AddMoneyToPP(uint32 copper, uint32 silver, uint32 gold, uint32 plat
gettimeofday(&read_time, 0);
sprintf(buffer, "%li.%li \n", read_time.tv_sec, read_time.tv_usec);
this->SetEntityVariable("Stop_Return", buffer);
}
void Client::AddMoneyToPP(uint32 copper, uint32 silver, uint32 gold, uint32 platinum, bool updateclient){
this->EVENT_ITEM_ScriptStopReturn();
int32 new_value = m_pp.platinum + platinum;
if(new_value >= 0 && new_value > m_pp.platinum)
@@ -2270,7 +2238,7 @@ void Client::AddMoneyToPP(uint32 copper, uint32 silver, uint32 gold, uint32 plat
SendMoneyUpdate();
RecalcWeight();
Save();
SaveCurrency();
#if (EQDEBUG>=5)
LogFile->write(EQEMuLog::Debug, "Client::AddMoneyToPP() %s should have: plat:%i gold:%i silver:%i copper:%i",
@@ -2352,12 +2320,14 @@ bool Client::CheckIncreaseSkill(SkillUseTypes skillid, Mob *against_who, int cha
{
// the higher your current skill level, the harder it is
int16 Chance = 10 + chancemodi + ((252 - skillval) / 20);
if (Chance < 1)
Chance = 1; // Make it always possible
Chance = (Chance * RuleI(Character, SkillUpModifier) / 100);
Chance = mod_increase_skill_chance(Chance, against_who);
if(Chance < 1)
Chance = 1; // Make it always possible
if(MakeRandomFloat(0, 99) < Chance)
{
SetSkill(skillid, GetRawSkill(skillid) + 1);
@@ -2807,11 +2777,6 @@ void Client::SetMaterial(int16 in_slot, uint32 item_id) {
m_pp.item_material[MaterialArms] = item->Material;
else if (in_slot==MainWrist1)
m_pp.item_material[MaterialWrist] = item->Material;
/*
// non-live behavior
else if (in_slot==SLOT_BRACER02)
m_pp.item_material[MaterialWrist] = item->Material;
*/
else if (in_slot==MainHands)
m_pp.item_material[MaterialHands] = item->Material;
else if (in_slot==MainLegs)
@@ -3146,6 +3111,7 @@ void Client::SetTint(int16 in_slot, uint32 color) {
Color_Struct new_color;
new_color.color = color;
SetTint(in_slot, new_color);
database.SaveCharacterMaterialColor(this->CharacterID(), in_slot, color);
}
// Still need to reconcile bracer01 versus bracer02
@@ -3173,6 +3139,8 @@ void Client::SetTint(int16 in_slot, Color_Struct& color) {
m_pp.item_tint[MaterialLegs].color=color.color;
else if (in_slot==MainFeet)
m_pp.item_tint[MaterialFeet].color=color.color;
database.SaveCharacterMaterialColor(this->CharacterID(), in_slot, color.color);
}
void Client::SetHideMe(bool flag)
@@ -3207,6 +3175,7 @@ void Client::SetLanguageSkill(int langid, int value)
value = 100; //Max lang value
m_pp.languages[langid] = value;
database.SaveCharacterLanguage(this->CharacterID(), langid, value);
EQApplicationPacket* outapp = new EQApplicationPacket(OP_SkillUpdate, sizeof(SkillUpdate_Struct));
SkillUpdate_Struct* skill = (SkillUpdate_Struct*)outapp->pBuffer;
@@ -4278,7 +4247,6 @@ void Client::VoiceMacroReceived(uint32 Type, char *Target, uint32 MacroNumber) {
}
void Client::ClearGroupAAs() {
for(unsigned int i = 0; i < MAX_GROUP_LEADERSHIP_AA_ARRAY; i++)
m_pp.leader_abilities.ranks[i] = 0;
@@ -4288,28 +4256,18 @@ void Client::ClearGroupAAs() {
m_pp.raid_leadership_exp = 0;
Save();
database.SaveCharacterLeadershipAA(this->CharacterID(), &m_pp);
}
void Client::UpdateGroupAAs(int32 points, uint32 type) {
switch(type)
{
case 0:
{
m_pp.group_leadership_points += points;
break;
}
case 1:
{
m_pp.raid_leadership_points += points;
break;
}
switch(type) {
case 0: { m_pp.group_leadership_points += points; break; }
case 1: { m_pp.raid_leadership_points += points; break; }
}
SendLeadershipEXPUpdate();
}
bool Client::IsLeadershipEXPOn()
{
bool Client::IsLeadershipEXPOn() {
if(!m_pp.leadAAActive)
return false;
@@ -5726,7 +5684,7 @@ void Client::AddCrystals(uint32 Radiant, uint32 Ebon)
m_pp.currentEbonCrystals += Ebon;
m_pp.careerEbonCrystals += Ebon;
Save();
SaveCurrency();
SendCrystalCounts();
}
@@ -8032,7 +7990,7 @@ void Client::RefundAA() {
for(int j = 0; j < cur; j++) {
m_pp.aapoints += curaa->cost + (curaa->cost_inc * j);
refunded = true;
}
}
}
else
{
@@ -8044,8 +8002,9 @@ void Client::RefundAA() {
}
if(refunded) {
SaveAA();
Save();
Kick();
// Kick();
}
}
@@ -8060,7 +8019,7 @@ void Client::IncrementAA(int aa_id) {
SetAA(aa_id, GetAA(aa_id) + 1);
Save();
SaveAA();
SendAA(aa_id);
SendAATable();
@@ -8354,3 +8313,18 @@ float Client::GetQuiverHaste()
quiver_haste = 1.0f / (1.0f + static_cast<float>(quiver_haste) / 100.0f);
return quiver_haste;
}
void Client::SendColoredText(uint32 color, std::string message)
{
// arbitrary size limit
if (message.size() > 512) // live does send this with empty strings sometimes ...
return;
EQApplicationPacket *outapp = new EQApplicationPacket(OP_ColoredText,
sizeof(ColoredText_Struct) + message.size());
ColoredText_Struct *cts = (ColoredText_Struct *)outapp->pBuffer;
cts->color = color;
strcpy(cts->msg, message.c_str());
QueuePacket(outapp);
safe_delete(outapp);
}
+11 -11
View File
@@ -37,6 +37,7 @@ class Client;
#include "../common/item_struct.h"
#include "../common/clientversions.h"
#include "common.h"
#include "zonedb.h"
#include "errno.h"
#include "mob.h"
@@ -102,11 +103,6 @@ enum { //scribing argument to MemorizeSpell
memSpellSpellbar = 3
};
#define USE_ITEM_SPELL_SLOT 10
#define POTION_BELT_SPELL_SLOT 11
#define DISCIPLINE_SPELL_SLOT 10
#define ABILITY_SPELL_SLOT 9
//Modes for the zoning state of the client.
typedef enum {
ZoneToSafeCoords, // Always send ZonePlayerToBind_Struct to client: Succor/Evac
@@ -240,8 +236,6 @@ public:
bool KeyRingCheck(uint32 item_id);
void KeyRingList();
virtual bool IsClient() const { return true; }
virtual void DBAWComplete(uint8 workpt_b1, DBAsyncWork* dbaw);
bool FinishConnState2(DBAsyncWork* dbaw);
void CompleteConnect();
bool TryStacking(ItemInst* item, uint8 type = ItemPacketTrade, bool try_worn = true, bool try_cursor = true);
void SendTraderPacket(Client* trader, uint32 Unknown72 = 51);
@@ -261,6 +255,7 @@ public:
const char *message7 = nullptr, const char *message8 = nullptr,
const char *message9 = nullptr);
void Tell_StringID(uint32 string_id, const char *who, const char *message);
void SendColoredText(uint32 color, std::string message);
void SendBazaarResults(uint32 trader_id,uint32 class_,uint32 race,uint32 stat,uint32 slot,uint32 type,char name[64],uint32 minprice,uint32 maxprice);
void SendTraderItem(uint32 item_id,uint16 quantity);
uint16 FindTraderItem(int32 SerialNumber,uint16 Quantity);
@@ -316,6 +311,10 @@ public:
bool Save(uint8 iCommitNow); // 0 = delayed, 1=async now, 2=sync now
void SaveBackup();
/* New PP Save Functions */
bool SaveCurrency(){ return database.SaveCharacterCurrency(this->CharacterID(), &m_pp); }
bool SaveAA();
inline bool ClientDataLoaded() const { return client_data_loaded; }
inline bool Connected() const { return (client_state == CLIENT_CONNECTED); }
inline bool InZone() const { return (client_state == CLIENT_CONNECTED || client_state == CLIENT_LINKDEAD); }
@@ -658,14 +657,14 @@ public:
void OnDisconnect(bool hard_disconnect);
uint16 GetSkillPoints() {return m_pp.points;}
void SetSkillPoints(int inp) {m_pp.points = inp;}
uint16 GetSkillPoints() { return m_pp.points;}
void SetSkillPoints(int inp) { m_pp.points = inp;}
void IncreaseSkill(int skill_id, int value = 1) { if (skill_id <= HIGHEST_SKILL) { m_pp.skills[skill_id] += value; } }
void IncreaseLanguageSkill(int skill_id, int value = 1);
virtual uint16 GetSkill(SkillUseTypes skill_id) const { if (skill_id <= HIGHEST_SKILL) { return((itembonuses.skillmod[skill_id] > 0)? m_pp.skills[skill_id]*(100 + itembonuses.skillmod[skill_id])/100 : m_pp.skills[skill_id]); } return 0; }
virtual uint16 GetSkill(SkillUseTypes skill_id) const { if (skill_id <= HIGHEST_SKILL) { return((itembonuses.skillmod[skill_id] > 0) ? m_pp.skills[skill_id] * (100 + itembonuses.skillmod[skill_id]) / 100 : m_pp.skills[skill_id]); } return 0; }
uint32 GetRawSkill(SkillUseTypes skill_id) const { if (skill_id <= HIGHEST_SKILL) { return(m_pp.skills[skill_id]); } return 0; }
bool HasSkill(SkillUseTypes skill_id) const;
bool HasSkill(SkillUseTypes skill_id) const;
bool CanHaveSkill(SkillUseTypes skill_id) const;
void SetSkill(SkillUseTypes skill_num, uint16 value);
void AddSkill(SkillUseTypes skillid, uint16 value);
@@ -786,6 +785,7 @@ public:
int16 acmod();
// Item methods
void EVENT_ITEM_ScriptStopReturn();
uint32 NukeItem(uint32 itemnum, uint8 where_to_check =
(invWhereWorn | invWherePersonal | invWhereBank | invWhereSharedBank | invWhereTrading | invWhereCursor));
void SetTint(int16 slot_id, uint32 color);
+2 -3
View File
@@ -33,14 +33,12 @@ void ClientLogs::subscribe(EQEMuLog::LogIDs id, Client *c) {
if(c == nullptr)
return;
//make sure they arnt allready subscribed.
std::vector<Client *>::iterator cur,end;
cur = entries[id].begin();
end = entries[id].end();
for(; cur != end; ++cur) {
if(*cur == c) {
printf("%s was allready subscribed to %d\n", c->GetName(), id);
printf("%s was already subscribed to %d\n", c->GetName(), id);
return;
}
}
@@ -100,6 +98,7 @@ void ClientLogs::msg(EQEMuLog::LogIDs id, const char *buf) {
for(; cur != end; ++cur) {
if(!(*cur)->InZone())
continue;
(*cur)->Message(CLIENT_LOG_CHANNEL, buf);
}
}
+40 -15
View File
@@ -1341,12 +1341,45 @@ int16 Client::CalcCHA() {
return(CHA);
}
int Client::CalcHaste() {
int h = spellbonuses.haste + spellbonuses.hastetype2;
int Client::CalcHaste()
{
/* Tests: (based on results in newer char window)
* 68 v1 + 46 item + 25 over + 35 inhib = 204%
* 46 item + 5 v2 + 25 over + 35 inhib = 65%
* 68 v1 + 46 item + 5 v2 + 25 over + 35 inhib = 209%
* 75% slow + 35 inhib = 25%
* 35 inhib = 65%
* 75% slow = 25%
* Conclusions:
* the bigger effect in slow v. inhib wins
* slow negates all other hastes
* inhib will only negate all other hastes if you don't have v1 (ex. VQ)
*/
// slow beats all! Besides a better inhibit
if (spellbonuses.haste < 0) {
if (-spellbonuses.haste <= spellbonuses.inhibitmelee)
Haste = 100 - spellbonuses.inhibitmelee;
else
Haste = 100 + spellbonuses.haste;
return Haste;
}
// No haste and inhibit, kills all other hastes
if (spellbonuses.haste == 0 && spellbonuses.inhibitmelee) {
Haste = 100 - spellbonuses.inhibitmelee;
return Haste;
}
int h = 0;
int cap = 0;
int overhaste = 0;
int level = GetLevel();
// we know we have a haste spell and not slowed, no extra inhibit melee checks needed
if (spellbonuses.haste)
h += spellbonuses.haste - spellbonuses.inhibitmelee;
if (spellbonuses.hastetype2 && level > 49) // type 2 is capped at 10% and only available to 50+
h += spellbonuses.hastetype2 > 10 ? 10 : spellbonuses.hastetype2;
// 26+ no cap, 1-25 10
if (level > 25) // 26+
h += itembonuses.haste;
@@ -1368,24 +1401,16 @@ int Client::CalcHaste() {
// 51+ 25 (despite there being higher spells...), 1-50 10
if (level > 50) // 51+
overhaste = spellbonuses.hastetype3 > 25 ? 25 : spellbonuses.hastetype3;
h += spellbonuses.hastetype3 > 25 ? 25 : spellbonuses.hastetype3;
else // 1-50
overhaste = spellbonuses.hastetype3 > 10 ? 10 : spellbonuses.hastetype3;
h += spellbonuses.hastetype3 > 10 ? 10 : spellbonuses.hastetype3;
h += overhaste;
h += ExtraHaste; //GM granted haste.
h = mod_client_haste(h);
if (spellbonuses.inhibitmelee) {
if (h >= 0)
h -= spellbonuses.inhibitmelee;
else
h -= ((100 + h) * spellbonuses.inhibitmelee / 100);
}
Haste = h;
return(Haste);
Haste = 100 + h;
return Haste;
}
//The AA multipliers are set to be 5, but were 2 on WR
+11993 -11998
View File
File diff suppressed because it is too large Load Diff
+280 -278
View File
@@ -1,292 +1,294 @@
void Handle_Connect_OP_SetDataRate(const EQApplicationPacket *app);
void Handle_Connect_OP_ZoneEntry(const EQApplicationPacket *app);
void Handle_Connect_OP_SetServerFilter(const EQApplicationPacket *app);
void Handle_Connect_OP_SendAATable(const EQApplicationPacket *app);
void Handle_Connect_OP_SendTributes(const EQApplicationPacket *app);
void Handle_Connect_OP_SendGuildTributes(const EQApplicationPacket *app);
void Handle_Connect_OP_SendAAStats(const EQApplicationPacket *app);
// connecting opcode handlers
void Handle_Connect_0x3e33(const EQApplicationPacket *app);
void Handle_Connect_OP_ApproveZone(const EQApplicationPacket *app);
void Handle_Connect_OP_ClientError(const EQApplicationPacket *app);
void Handle_Connect_OP_ClientReady(const EQApplicationPacket *app);
void Handle_Connect_OP_ClientUpdate(const EQApplicationPacket *app);
void Handle_Connect_OP_ReqClientSpawn(const EQApplicationPacket *app);
void Handle_Connect_OP_ReqNewZone(const EQApplicationPacket *app);
void Handle_Connect_OP_SendAAStats(const EQApplicationPacket *app);
void Handle_Connect_OP_SendAATable(const EQApplicationPacket *app);
void Handle_Connect_OP_SendExpZonein(const EQApplicationPacket *app);
void Handle_Connect_OP_SendGuildTributes(const EQApplicationPacket *app);
void Handle_Connect_OP_SendTributes(const EQApplicationPacket *app);
void Handle_Connect_OP_SetDataRate(const EQApplicationPacket *app);
void Handle_Connect_OP_SetServerFilter(const EQApplicationPacket *app);
void Handle_Connect_OP_SpawnAppearance(const EQApplicationPacket *app);
void Handle_Connect_OP_TGB(const EQApplicationPacket *app);
void Handle_Connect_OP_UpdateAA(const EQApplicationPacket *app);
void Handle_Connect_OP_WearChange(const EQApplicationPacket *app);
void Handle_Connect_OP_WorldObjectsSent(const EQApplicationPacket *app);
void Handle_Connect_OP_ZoneComplete(const EQApplicationPacket *app);
void Handle_Connect_OP_ReqNewZone(const EQApplicationPacket *app);
void Handle_Connect_OP_SpawnAppearance(const EQApplicationPacket *app);
void Handle_Connect_OP_WearChange(const EQApplicationPacket *app);
void Handle_Connect_OP_ClientUpdate(const EQApplicationPacket *app);
void Handle_Connect_OP_ClientError(const EQApplicationPacket *app);
void Handle_Connect_OP_ApproveZone(const EQApplicationPacket *app);
void Handle_Connect_OP_ClientReady(const EQApplicationPacket *app);
void Handle_Connect_OP_UpdateAA(const EQApplicationPacket *app);
void Handle_Connect_OP_TGB(const EQApplicationPacket *app);
void Handle_OP_ClientUpdate(const EQApplicationPacket *app);
void Handle_OP_AutoAttack(const EQApplicationPacket *app);
void Handle_OP_AutoAttack2(const EQApplicationPacket *app);
void Handle_OP_Consent(const EQApplicationPacket *app);
void Handle_OP_ConsentDeny(const EQApplicationPacket *app);
void Handle_OP_TargetMouse(const EQApplicationPacket *app);
void Handle_OP_TargetCommand(const EQApplicationPacket *app);
void Handle_OP_Shielding(const EQApplicationPacket *app);
void Handle_OP_Jump(const EQApplicationPacket *app);
void Handle_OP_AdventureInfoRequest(const EQApplicationPacket *app);
void Handle_OP_AdventureRequest(const EQApplicationPacket *app);
void Handle_OP_LDoNButton(const EQApplicationPacket *app);
void Handle_OP_LeaveAdventure(const EQApplicationPacket *app);
void Handle_OP_Consume(const EQApplicationPacket *app);
void Handle_OP_ItemVerifyRequest(const EQApplicationPacket *app);
void Handle_OP_AdventureMerchantRequest(const EQApplicationPacket *app);
void Handle_OP_AdventureMerchantPurchase(const EQApplicationPacket *app);
void Handle_OP_ConsiderCorpse(const EQApplicationPacket *app);
void Handle_OP_Consider(const EQApplicationPacket *app);
void Handle_OP_Begging(const EQApplicationPacket *app);
void Handle_OP_TestBuff(const EQApplicationPacket *app);
void Handle_OP_Surname(const EQApplicationPacket *app);
void Handle_OP_ClearSurname(const EQApplicationPacket *app);
void Handle_OP_YellForHelp(const EQApplicationPacket *app);
void Handle_OP_Assist(const EQApplicationPacket *app);
void Handle_OP_AssistGroup(const EQApplicationPacket *app);
void Handle_OP_GMTraining(const EQApplicationPacket *app);
void Handle_OP_GMEndTraining(const EQApplicationPacket *app);
void Handle_OP_GMTrainSkill(const EQApplicationPacket *app);
void Handle_OP_DuelResponse(const EQApplicationPacket *app);
void Handle_OP_DuelResponse2(const EQApplicationPacket *app);
void Handle_OP_RequestDuel(const EQApplicationPacket *app);
void Handle_OP_SpawnAppearance(const EQApplicationPacket *app);
void Handle_OP_BazaarInspect(const EQApplicationPacket *app);
void Handle_OP_Death(const EQApplicationPacket *app);
void Handle_OP_MoveCoin(const EQApplicationPacket *app);
void Handle_OP_ItemLinkClick(const EQApplicationPacket *app);
void Handle_OP_ItemLinkResponse(const EQApplicationPacket *app);
void Handle_OP_MoveItem(const EQApplicationPacket *app);
void Handle_OP_Camp(const EQApplicationPacket *app);
void Handle_OP_Logout(const EQApplicationPacket *app);
void Handle_OP_SenseHeading(const EQApplicationPacket *app);
void Handle_OP_LDoNOpen(const EQApplicationPacket *app);
void Handle_OP_LDoNDisarmTraps(const EQApplicationPacket *app);
void Handle_OP_LDoNSenseTraps(const EQApplicationPacket *app);
void Handle_OP_LDoNInspect(const EQApplicationPacket *app);
void Handle_OP_LDoNPickLock(const EQApplicationPacket *app);
void Handle_OP_FeignDeath(const EQApplicationPacket *app);
void Handle_OP_Sneak(const EQApplicationPacket *app);
void Handle_OP_Hide(const EQApplicationPacket *app);
void Handle_OP_ChannelMessage(const EQApplicationPacket *app);
void Handle_OP_WearChange(const EQApplicationPacket *app);
void Handle_OP_ZoneChange(const EQApplicationPacket *app);
void Handle_OP_DeleteSpawn(const EQApplicationPacket *app);
void Handle_OP_SaveOnZoneReq(const EQApplicationPacket *app);
void Handle_OP_Save(const EQApplicationPacket *app);
void Handle_OP_WhoAllRequest(const EQApplicationPacket *app);
void Handle_OP_GMZoneRequest(const EQApplicationPacket *app);
void Handle_OP_GMZoneRequest2(const EQApplicationPacket *app);
void Handle_OP_EndLootRequest(const EQApplicationPacket *app);
void Handle_OP_LootRequest(const EQApplicationPacket *app);
void Handle_OP_Dye(const EQApplicationPacket *app);
void Handle_OP_LootItem(const EQApplicationPacket *app);
void Handle_OP_GuildDelete(const EQApplicationPacket *app);
void Handle_OP_GuildPublicNote(const EQApplicationPacket *app);
void Handle_OP_GetGuildsList(const EQApplicationPacket *app);
void Handle_OP_SetGuildMOTD(const EQApplicationPacket *app);
void Handle_OP_GuildPeace(const EQApplicationPacket *app);
void Handle_OP_GuildWar(const EQApplicationPacket *app);
void Handle_OP_GuildLeader(const EQApplicationPacket *app);
void Handle_OP_GuildDemote(const EQApplicationPacket *app);
void Handle_OP_GuildPromote(const EQApplicationPacket *app);
void Handle_OP_GuildInvite(const EQApplicationPacket *app);
void Handle_OP_GuildRemove(const EQApplicationPacket *app);
void Handle_OP_GetGuildMOTD(const EQApplicationPacket *app);
void Handle_OP_GuildManageBanker(const EQApplicationPacket *app);
void Handle_OP_GuildInviteAccept(const EQApplicationPacket *app);
void Handle_OP_ManaChange(const EQApplicationPacket *app);
void Handle_OP_MemorizeSpell(const EQApplicationPacket *app);
void Handle_OP_SwapSpell(const EQApplicationPacket *app);
void Handle_OP_CastSpell(const EQApplicationPacket *app);
void Handle_OP_DeleteItem(const EQApplicationPacket *app);
void Handle_OP_CombatAbility(const EQApplicationPacket *app);
void Handle_OP_Taunt(const EQApplicationPacket *app);
void Handle_OP_InstillDoubt(const EQApplicationPacket *app);
void Handle_OP_RezzAnswer(const EQApplicationPacket *app);
void Handle_OP_GMSummon(const EQApplicationPacket *app);
void Handle_OP_TradeRequest(const EQApplicationPacket *app);
void Handle_OP_TradeRequestAck(const EQApplicationPacket *app);
void Handle_OP_CancelTrade(const EQApplicationPacket *app);
void Handle_OP_TradeAcceptClick(const EQApplicationPacket *app);
void Handle_OP_BoardBoat(const EQApplicationPacket *app);
void Handle_OP_LeaveBoat(const EQApplicationPacket *app);
void Handle_OP_RandomReq(const EQApplicationPacket *app);
void Handle_OP_Buff(const EQApplicationPacket *app);
void Handle_OP_GMHideMe(const EQApplicationPacket *app);
void Handle_OP_GMNameChange(const EQApplicationPacket *app);
void Handle_OP_GMKill(const EQApplicationPacket *app);
void Handle_OP_GMLastName(const EQApplicationPacket *app);
void Handle_OP_GMToggle(const EQApplicationPacket *app);
void Handle_OP_LFGCommand(const EQApplicationPacket *app);
void Handle_OP_GMGoto(const EQApplicationPacket *app);
void Handle_OP_TraderShop(const EQApplicationPacket *app);
void Handle_OP_ShopRequest(const EQApplicationPacket *app);
void Handle_OP_BazaarSearch(const EQApplicationPacket *app);
void Handle_OP_ShopPlayerBuy(const EQApplicationPacket *app);
void Handle_OP_ShopPlayerSell(const EQApplicationPacket *app);
void Handle_OP_ShopEnd(const EQApplicationPacket *app);
// void Handle_OP_CloseContainer(const EQApplicationPacket *app);
void Handle_OP_ClickObjectAction(const EQApplicationPacket *app);
void Handle_OP_ClickObject(const EQApplicationPacket *app);
void Handle_OP_RecipesFavorite(const EQApplicationPacket *app);
void Handle_OP_RecipesSearch(const EQApplicationPacket *app);
void Handle_OP_RecipeDetails(const EQApplicationPacket *app);
void Handle_OP_RecipeAutoCombine(const EQApplicationPacket *app);
void Handle_OP_TradeSkillCombine(const EQApplicationPacket *app);
void Handle_OP_ItemName(const EQApplicationPacket *app);
void Handle_OP_AugmentItem(const EQApplicationPacket *app);
void Handle_OP_ClickDoor(const EQApplicationPacket *app);
void Handle_OP_CreateObject(const EQApplicationPacket *app);
void Handle_OP_FaceChange(const EQApplicationPacket *app);
void Handle_OP_GroupInvite(const EQApplicationPacket *app);
void Handle_OP_GroupInvite2(const EQApplicationPacket *app);
void Handle_OP_GroupAcknowledge(const EQApplicationPacket *app);
void Handle_OP_GroupCancelInvite(const EQApplicationPacket *app);
void Handle_OP_GroupFollow(const EQApplicationPacket *app);
void Handle_OP_GroupFollow2(const EQApplicationPacket *app);
void Handle_OP_GroupDisband(const EQApplicationPacket *app);
void Handle_OP_GroupDelete(const EQApplicationPacket *app);
void Handle_OP_GMEmoteZone(const EQApplicationPacket *app);
void Handle_OP_InspectRequest(const EQApplicationPacket *app);
void Handle_OP_InspectAnswer(const EQApplicationPacket *app);
void Handle_OP_InspectMessageUpdate(const EQApplicationPacket *app);
void Handle_OP_Medding(const EQApplicationPacket *app);
void Handle_OP_DeleteSpell(const EQApplicationPacket *app);
void Handle_OP_PetitionBug(const EQApplicationPacket *app);
void Handle_OP_Bug(const EQApplicationPacket *app);
void Handle_OP_Petition(const EQApplicationPacket *app);
void Handle_OP_PetitionCheckIn(const EQApplicationPacket *app);
void Handle_OP_PetitionResolve(const EQApplicationPacket *app);
void Handle_OP_PetitionDelete(const EQApplicationPacket *app);
void Handle_OP_PetCommands(const EQApplicationPacket *app);
void Handle_OP_PetitionUnCheckout(const EQApplicationPacket *app);
void Handle_OP_PetitionQue(const EQApplicationPacket *app);
void Handle_OP_PDeletePetition(const EQApplicationPacket *app);
void Handle_OP_PetitionCheckout(const EQApplicationPacket *app);
void Handle_OP_PetitionRefresh(const EQApplicationPacket *app);
void Handle_OP_ReadBook(const EQApplicationPacket *app);
void Handle_OP_Emote(const EQApplicationPacket *app);
void Handle_OP_Animation(const EQApplicationPacket *app);
void Handle_OP_SetServerFilter(const EQApplicationPacket *app);
void Handle_OP_GMDelCorpse(const EQApplicationPacket *app);
void Handle_OP_GMKick(const EQApplicationPacket *app);
void Handle_OP_GMServers(const EQApplicationPacket *app);
void Handle_OP_Illusion(const EQApplicationPacket *app);
void Handle_OP_GMBecomeNPC(const EQApplicationPacket *app);
void Handle_OP_Fishing(const EQApplicationPacket *app);
void Handle_OP_Forage(const EQApplicationPacket *app);
void Handle_OP_Mend(const EQApplicationPacket *app);
void Handle_OP_EnvDamage(const EQApplicationPacket *app);
void Handle_OP_Damage(const EQApplicationPacket *app);
void Handle_OP_AAAction(const EQApplicationPacket *app);
void Handle_OP_TraderBuy(const EQApplicationPacket *app);
void Handle_OP_Trader(const EQApplicationPacket *app);
void Handle_OP_GMFind(const EQApplicationPacket *app);
void Handle_OP_PickPocket(const EQApplicationPacket *app);
void Handle_OP_Bind_Wound(const EQApplicationPacket *app);
void Handle_OP_TrackTarget(const EQApplicationPacket *app);
void Handle_OP_Track(const EQApplicationPacket *app);
void Handle_OP_TrackUnknown(const EQApplicationPacket *app);
void Handle_Connect_OP_ZoneEntry(const EQApplicationPacket *app);
// connected opcode handlers
void Handle_0x0193(const EQApplicationPacket *app);
void Handle_0x01e7(const EQApplicationPacket *app);
void Handle_OP_ClientError(const EQApplicationPacket *app);
void Handle_OP_ReloadUI(const EQApplicationPacket *app);
void Handle_OP_TGB(const EQApplicationPacket *app);
void Handle_OP_Split(const EQApplicationPacket *app);
void Handle_OP_SenseTraps(const EQApplicationPacket *app);
void Handle_OP_DisarmTraps(const EQApplicationPacket *app);
void Handle_OP_OpenTributeMaster(const EQApplicationPacket *app);
void Handle_OP_OpenGuildTributeMaster(const EQApplicationPacket *app);
void Handle_OP_TributeItem(const EQApplicationPacket *app);
void Handle_OP_TributeMoney(const EQApplicationPacket *app);
void Handle_OP_SelectTribute(const EQApplicationPacket *app);
void Handle_OP_TributeUpdate(const EQApplicationPacket *app);
void Handle_OP_TributeToggle(const EQApplicationPacket *app);
void Handle_OP_TributeNPC(const EQApplicationPacket *app);
void Handle_OP_ConfirmDelete(const EQApplicationPacket *app);
void Handle_OP_CrashDump(const EQApplicationPacket *app);
void Handle_OP_ControlBoat(const EQApplicationPacket *app);
void Handle_OP_DumpName(const EQApplicationPacket *app);
void Handle_OP_SetRunMode(const EQApplicationPacket *app);
void Handle_OP_SafeFallSuccess(const EQApplicationPacket *app);
void Handle_OP_Heartbeat(const EQApplicationPacket *app);
void Handle_OP_SafePoint(const EQApplicationPacket *app);
void Handle_OP_FindPersonRequest(const EQApplicationPacket *app);
void Handle_OP_BankerChange(const EQApplicationPacket *app);
void Handle_OP_LeadershipExpToggle(const EQApplicationPacket *app);
void Handle_OP_SetTitle(const EQApplicationPacket *app);
void Handle_OP_RequestTitles(const EQApplicationPacket *app);
void Handle_OP_PurchaseLeadershipAA(const EQApplicationPacket *app);
void Handle_OP_Ignore(const EQApplicationPacket *app);
void Handle_OP_LoadSpellSet(const EQApplicationPacket *app);
void Handle_OP_AutoFire(const EQApplicationPacket *app);
void Handle_OP_Rewind(const EQApplicationPacket *app);
void Handle_OP_RaidCommand(const EQApplicationPacket *app);
void Handle_OP_Translocate(const EQApplicationPacket *app);
void Handle_OP_Sacrifice(const EQApplicationPacket *app);
void Handle_OP_AAAction(const EQApplicationPacket *app);
void Handle_OP_AcceptNewTask(const EQApplicationPacket *app);
void Handle_OP_CancelTask(const EQApplicationPacket *app);
void Handle_OP_TaskHistoryRequest(const EQApplicationPacket *app);
void Handle_OP_KeyRing(const EQApplicationPacket *app);
void Handle_OP_FriendsWho(const EQApplicationPacket *app);
void Handle_OP_Bandolier(const EQApplicationPacket *app);
void Handle_OP_PopupResponse(const EQApplicationPacket *app);
void Handle_OP_PotionBelt(const EQApplicationPacket *app);
void Handle_OP_LFGGetMatchesRequest(const EQApplicationPacket *app);
void Handle_OP_LFPCommand(const EQApplicationPacket *app);
void Handle_OP_LFPGetMatchesRequest(const EQApplicationPacket *app);
void Handle_OP_Barter(const EQApplicationPacket *app);
void Handle_OP_VoiceMacroIn(const EQApplicationPacket *app);
void Handle_OP_DoGroupLeadershipAbility(const EQApplicationPacket *app);
void Handle_OP_ClearNPCMarks(const EQApplicationPacket *app);
void Handle_OP_DelegateAbility(const EQApplicationPacket *app);
void Handle_OP_ApplyPoison(const EQApplicationPacket *app);
void Handle_OP_AugmentInfo(const EQApplicationPacket *app);
void Handle_OP_PVPLeaderBoardRequest(const EQApplicationPacket *app);
void Handle_OP_PVPLeaderBoardDetailsRequest(const EQApplicationPacket *app);
void Handle_OP_AdventureMerchantSell(const EQApplicationPacket *app);
void Handle_OP_AdventureStatsRequest(const EQApplicationPacket *app);
void Handle_OP_AdventureInfoRequest(const EQApplicationPacket *app);
void Handle_OP_AdventureLeaderboardRequest(const EQApplicationPacket *app);
void Handle_OP_RespawnWindow(const EQApplicationPacket *app);
void Handle_OP_GroupUpdate(const EQApplicationPacket *app);
void Handle_OP_SetStartCity(const EQApplicationPacket *app);
void Handle_OP_Report(const EQApplicationPacket *app);
void Handle_OP_VetClaimRequest(const EQApplicationPacket *app);
void Handle_OP_GMSearchCorpse(const EQApplicationPacket *app);
void Handle_OP_GuildBank(const EQApplicationPacket *app);
void Handle_OP_GroupRoles(const EQApplicationPacket *app);
void Handle_OP_HideCorpse(const EQApplicationPacket *app);
void Handle_OP_TradeBusy(const EQApplicationPacket *app);
void Handle_OP_GuildUpdateURLAndChannel(const EQApplicationPacket *app);
void Handle_OP_GuildStatus(const EQApplicationPacket *app);
void Handle_OP_BlockedBuffs(const EQApplicationPacket *app);
void Handle_OP_RemoveBlockedBuffs(const EQApplicationPacket *app);
void Handle_OP_ClearBlockedBuffs(const EQApplicationPacket *app);
void Handle_OP_BuffRemoveRequest(const EQApplicationPacket *app);
void Handle_OP_CorpseDrag(const EQApplicationPacket *app);
void Handle_OP_CorpseDrop(const EQApplicationPacket *app);
void Handle_OP_GroupMakeLeader(const EQApplicationPacket *app);
void Handle_OP_GuildCreate(const EQApplicationPacket *app);
void Handle_OP_AdventureMerchantPurchase(const EQApplicationPacket *app);
void Handle_OP_AdventureMerchantRequest(const EQApplicationPacket *app);
void Handle_OP_AdventureMerchantSell(const EQApplicationPacket *app);
void Handle_OP_AdventureRequest(const EQApplicationPacket *app);
void Handle_OP_AdventureStatsRequest(const EQApplicationPacket *app);
void Handle_OP_AltCurrencyMerchantRequest(const EQApplicationPacket *app);
void Handle_OP_AltCurrencySellSelection(const EQApplicationPacket *app);
void Handle_OP_AltCurrencyPurchase(const EQApplicationPacket *app);
void Handle_OP_AltCurrencyReclaim(const EQApplicationPacket *app);
void Handle_OP_AltCurrencySell(const EQApplicationPacket *app);
void Handle_OP_CrystalReclaim(const EQApplicationPacket *app);
void Handle_OP_CrystalCreate(const EQApplicationPacket *app);
void Handle_OP_LFGuild(const EQApplicationPacket *app);
void Handle_OP_XTargetRequest(const EQApplicationPacket *app);
void Handle_OP_XTargetAutoAddHaters(const EQApplicationPacket *app);
void Handle_OP_ItemPreview(const EQApplicationPacket *app);
void Handle_OP_MercenaryDataRequest(const EQApplicationPacket *app);
void Handle_OP_MercenaryHire(const EQApplicationPacket *app);
void Handle_OP_MercenaryCommand(const EQApplicationPacket *app);
void Handle_OP_MercenaryDataUpdateRequest(const EQApplicationPacket *app);
void Handle_OP_MercenarySuspendRequest(const EQApplicationPacket *app);
void Handle_OP_MercenaryDismiss(const EQApplicationPacket *app);
void Handle_OP_MercenaryTimerRequest(const EQApplicationPacket *app);
void Handle_OP_OpenInventory(const EQApplicationPacket *app);
void Handle_OP_OpenContainer(const EQApplicationPacket *app);
void Handle_OP_AltCurrencySellSelection(const EQApplicationPacket *app);
void Handle_OP_Animation(const EQApplicationPacket *app);
void Handle_OP_ApplyPoison(const EQApplicationPacket *app);
void Handle_OP_Assist(const EQApplicationPacket *app);
void Handle_OP_AssistGroup(const EQApplicationPacket *app);
void Handle_OP_AugmentInfo(const EQApplicationPacket *app);
void Handle_OP_AugmentItem(const EQApplicationPacket *app);
void Handle_OP_AutoAttack(const EQApplicationPacket *app);
void Handle_OP_AutoAttack2(const EQApplicationPacket *app);
void Handle_OP_AutoFire(const EQApplicationPacket *app);
void Handle_OP_Bandolier(const EQApplicationPacket *app);
void Handle_OP_BankerChange(const EQApplicationPacket *app);
void Handle_OP_Barter(const EQApplicationPacket *app);
void Handle_OP_BazaarInspect(const EQApplicationPacket *app);
void Handle_OP_BazaarSearch(const EQApplicationPacket *app);
void Handle_OP_Begging(const EQApplicationPacket *app);
void Handle_OP_Bind_Wound(const EQApplicationPacket *app);
void Handle_OP_BlockedBuffs(const EQApplicationPacket *app);
void Handle_OP_BoardBoat(const EQApplicationPacket *app);
void Handle_OP_Buff(const EQApplicationPacket *app);
void Handle_OP_BuffRemoveRequest(const EQApplicationPacket *app);
void Handle_OP_Bug(const EQApplicationPacket *app);
void Handle_OP_Camp(const EQApplicationPacket *app);
void Handle_OP_CancelTask(const EQApplicationPacket *app);
void Handle_OP_CancelTrade(const EQApplicationPacket *app);
void Handle_OP_CastSpell(const EQApplicationPacket *app);
void Handle_OP_ChannelMessage(const EQApplicationPacket *app);
void Handle_OP_ClearBlockedBuffs(const EQApplicationPacket *app);
void Handle_OP_ClearNPCMarks(const EQApplicationPacket *app);
void Handle_OP_ClearSurname(const EQApplicationPacket *app);
void Handle_OP_ClickDoor(const EQApplicationPacket *app);
void Handle_OP_ClickObject(const EQApplicationPacket *app);
void Handle_OP_ClickObjectAction(const EQApplicationPacket *app);
void Handle_OP_ClientError(const EQApplicationPacket *app);
void Handle_OP_ClientTimeStamp(const EQApplicationPacket *app);
void Handle_OP_ClientUpdate(const EQApplicationPacket *app);
// void Handle_OP_CloseContainer(const EQApplicationPacket *app);
void Handle_OP_CombatAbility(const EQApplicationPacket *app);
void Handle_OP_ConfirmDelete(const EQApplicationPacket *app);
void Handle_OP_Consent(const EQApplicationPacket *app);
void Handle_OP_ConsentDeny(const EQApplicationPacket *app);
void Handle_OP_Consider(const EQApplicationPacket *app);
void Handle_OP_ConsiderCorpse(const EQApplicationPacket *app);
void Handle_OP_Consume(const EQApplicationPacket *app);
void Handle_OP_ControlBoat(const EQApplicationPacket *app);
void Handle_OP_CorpseDrag(const EQApplicationPacket *app);
void Handle_OP_CorpseDrop(const EQApplicationPacket *app);
void Handle_OP_CrashDump(const EQApplicationPacket *app);
void Handle_OP_CreateObject(const EQApplicationPacket *app);
void Handle_OP_CrystalCreate(const EQApplicationPacket *app);
void Handle_OP_CrystalReclaim(const EQApplicationPacket *app);
void Handle_OP_Damage(const EQApplicationPacket *app);
void Handle_OP_Death(const EQApplicationPacket *app);
void Handle_OP_DelegateAbility(const EQApplicationPacket *app);
void Handle_OP_DeleteItem(const EQApplicationPacket *app);
void Handle_OP_DeleteSpawn(const EQApplicationPacket *app);
void Handle_OP_DeleteSpell(const EQApplicationPacket *app);
void Handle_OP_DisarmTraps(const EQApplicationPacket *app);
void Handle_OP_DoGroupLeadershipAbility(const EQApplicationPacket *app);
void Handle_OP_DuelResponse(const EQApplicationPacket *app);
void Handle_OP_DuelResponse2(const EQApplicationPacket *app);
void Handle_OP_DumpName(const EQApplicationPacket *app);
void Handle_OP_Dye(const EQApplicationPacket *app);
void Handle_OP_Emote(const EQApplicationPacket *app);
void Handle_OP_EndLootRequest(const EQApplicationPacket *app);
void Handle_OP_EnvDamage(const EQApplicationPacket *app);
void Handle_OP_FaceChange(const EQApplicationPacket *app);
void Handle_OP_FeignDeath(const EQApplicationPacket *app);
void Handle_OP_FindPersonRequest(const EQApplicationPacket *app);
void Handle_OP_Fishing(const EQApplicationPacket *app);
void Handle_OP_Forage(const EQApplicationPacket *app);
void Handle_OP_FriendsWho(const EQApplicationPacket *app);
void Handle_OP_GetGuildMOTD(const EQApplicationPacket *app);
void Handle_OP_GetGuildsList(const EQApplicationPacket *app);
void Handle_OP_GMBecomeNPC(const EQApplicationPacket *app);
void Handle_OP_GMDelCorpse(const EQApplicationPacket *app);
void Handle_OP_GMEmoteZone(const EQApplicationPacket *app);
void Handle_OP_GMEndTraining(const EQApplicationPacket *app);
void Handle_OP_GMFind(const EQApplicationPacket *app);
void Handle_OP_GMGoto(const EQApplicationPacket *app);
void Handle_OP_GMHideMe(const EQApplicationPacket *app);
void Handle_OP_GMKick(const EQApplicationPacket *app);
void Handle_OP_GMKill(const EQApplicationPacket *app);
void Handle_OP_GMLastName(const EQApplicationPacket *app);
void Handle_OP_GMNameChange(const EQApplicationPacket *app);
void Handle_OP_GMSearchCorpse(const EQApplicationPacket *app);
void Handle_OP_GMServers(const EQApplicationPacket *app);
void Handle_OP_GMSummon(const EQApplicationPacket *app);
void Handle_OP_GMToggle(const EQApplicationPacket *app);
void Handle_OP_GMTraining(const EQApplicationPacket *app);
void Handle_OP_GMTrainSkill(const EQApplicationPacket *app);
void Handle_OP_GMZoneRequest(const EQApplicationPacket *app);
void Handle_OP_GMZoneRequest2(const EQApplicationPacket *app);
void Handle_OP_GroupAcknowledge(const EQApplicationPacket *app);
void Handle_OP_GroupCancelInvite(const EQApplicationPacket *app);
void Handle_OP_GroupDelete(const EQApplicationPacket *app);
void Handle_OP_GroupDisband(const EQApplicationPacket *app);
void Handle_OP_GroupFollow(const EQApplicationPacket *app);
void Handle_OP_GroupFollow2(const EQApplicationPacket *app);
void Handle_OP_GroupInvite(const EQApplicationPacket *app);
void Handle_OP_GroupInvite2(const EQApplicationPacket *app);
void Handle_OP_GroupMakeLeader(const EQApplicationPacket *app);
void Handle_OP_GroupRoles(const EQApplicationPacket *app);
void Handle_OP_GroupUpdate(const EQApplicationPacket *app);
void Handle_OP_GuildBank(const EQApplicationPacket *app);
void Handle_OP_GuildCreate(const EQApplicationPacket *app);
void Handle_OP_GuildDelete(const EQApplicationPacket *app);
void Handle_OP_GuildDemote(const EQApplicationPacket *app);
void Handle_OP_GuildInvite(const EQApplicationPacket *app);
void Handle_OP_GuildInviteAccept(const EQApplicationPacket *app);
void Handle_OP_GuildLeader(const EQApplicationPacket *app);
void Handle_OP_GuildManageBanker(const EQApplicationPacket *app);
void Handle_OP_GuildPeace(const EQApplicationPacket *app);
void Handle_OP_GuildPromote(const EQApplicationPacket *app);
void Handle_OP_GuildPublicNote(const EQApplicationPacket *app);
void Handle_OP_GuildRemove(const EQApplicationPacket *app);
void Handle_OP_GuildStatus(const EQApplicationPacket *app);
void Handle_OP_GuildUpdateURLAndChannel(const EQApplicationPacket *app);
void Handle_OP_GuildWar(const EQApplicationPacket *app);
void Handle_OP_Heartbeat(const EQApplicationPacket *app);
void Handle_OP_Hide(const EQApplicationPacket *app);
void Handle_OP_HideCorpse(const EQApplicationPacket *app);
void Handle_OP_Ignore(const EQApplicationPacket *app);
void Handle_OP_Illusion(const EQApplicationPacket *app);
void Handle_OP_InspectAnswer(const EQApplicationPacket *app);
void Handle_OP_InspectMessageUpdate(const EQApplicationPacket *app);
void Handle_OP_InspectRequest(const EQApplicationPacket *app);
void Handle_OP_InstillDoubt(const EQApplicationPacket *app);
void Handle_OP_ItemLinkClick(const EQApplicationPacket *app);
void Handle_OP_ItemLinkResponse(const EQApplicationPacket *app);
void Handle_OP_ItemName(const EQApplicationPacket *app);
void Handle_OP_ItemPreview(const EQApplicationPacket *app);
void Handle_OP_ItemVerifyRequest(const EQApplicationPacket *app);
void Handle_OP_Jump(const EQApplicationPacket *app);
void Handle_OP_KeyRing(const EQApplicationPacket *app);
void Handle_OP_LDoNButton(const EQApplicationPacket *app);
void Handle_OP_LDoNDisarmTraps(const EQApplicationPacket *app);
void Handle_OP_LDoNInspect(const EQApplicationPacket *app);
void Handle_OP_LDoNOpen(const EQApplicationPacket *app);
void Handle_OP_LDoNPickLock(const EQApplicationPacket *app);
void Handle_OP_LDoNSenseTraps(const EQApplicationPacket *app);
void Handle_OP_LeadershipExpToggle(const EQApplicationPacket *app);
void Handle_OP_LeaveAdventure(const EQApplicationPacket *app);
void Handle_OP_LeaveBoat(const EQApplicationPacket *app);
void Handle_OP_LFGCommand(const EQApplicationPacket *app);
void Handle_OP_LFGGetMatchesRequest(const EQApplicationPacket *app);
void Handle_OP_LFGuild(const EQApplicationPacket *app);
void Handle_OP_LFPCommand(const EQApplicationPacket *app);
void Handle_OP_LFPGetMatchesRequest(const EQApplicationPacket *app);
void Handle_OP_LoadSpellSet(const EQApplicationPacket *app);
void Handle_OP_Logout(const EQApplicationPacket *app);
void Handle_OP_LootItem(const EQApplicationPacket *app);
void Handle_OP_LootRequest(const EQApplicationPacket *app);
void Handle_OP_ManaChange(const EQApplicationPacket *app);
void Handle_OP_Medding(const EQApplicationPacket *app);
void Handle_OP_MemorizeSpell(const EQApplicationPacket *app);
void Handle_OP_Mend(const EQApplicationPacket *app);
void Handle_OP_MercenaryCommand(const EQApplicationPacket *app);
void Handle_OP_MercenaryDataRequest(const EQApplicationPacket *app);
void Handle_OP_MercenaryDataUpdateRequest(const EQApplicationPacket *app);
void Handle_OP_MercenaryDismiss(const EQApplicationPacket *app);
void Handle_OP_MercenaryHire(const EQApplicationPacket *app);
void Handle_OP_MercenarySuspendRequest(const EQApplicationPacket *app);
void Handle_OP_MercenaryTimerRequest(const EQApplicationPacket *app);
void Handle_OP_MoveCoin(const EQApplicationPacket *app);
void Handle_OP_MoveItem(const EQApplicationPacket *app);
void Handle_OP_OpenContainer(const EQApplicationPacket *app);
void Handle_OP_OpenGuildTributeMaster(const EQApplicationPacket *app);
void Handle_OP_OpenInventory(const EQApplicationPacket *app);
void Handle_OP_OpenTributeMaster(const EQApplicationPacket *app);
void Handle_OP_PDeletePetition(const EQApplicationPacket *app);
void Handle_OP_PetCommands(const EQApplicationPacket *app);
void Handle_OP_Petition(const EQApplicationPacket *app);
void Handle_OP_PetitionBug(const EQApplicationPacket *app);
void Handle_OP_PetitionCheckIn(const EQApplicationPacket *app);
void Handle_OP_PetitionCheckout(const EQApplicationPacket *app);
void Handle_OP_PetitionDelete(const EQApplicationPacket *app);
void Handle_OP_PetitionQue(const EQApplicationPacket *app);
void Handle_OP_PetitionRefresh(const EQApplicationPacket *app);
void Handle_OP_PetitionResolve(const EQApplicationPacket *app);
void Handle_OP_PetitionUnCheckout(const EQApplicationPacket *app);
void Handle_OP_PickPocket(const EQApplicationPacket *app);
void Handle_OP_PopupResponse(const EQApplicationPacket *app);
void Handle_OP_PotionBelt(const EQApplicationPacket *app);
void Handle_OP_PurchaseLeadershipAA(const EQApplicationPacket *app);
void Handle_OP_PVPLeaderBoardDetailsRequest(const EQApplicationPacket *app);
void Handle_OP_PVPLeaderBoardRequest(const EQApplicationPacket *app);
void Handle_OP_RaidCommand(const EQApplicationPacket *app);
void Handle_OP_RandomReq(const EQApplicationPacket *app);
void Handle_OP_ReadBook(const EQApplicationPacket *app);
void Handle_OP_RecipeAutoCombine(const EQApplicationPacket *app);
void Handle_OP_RecipeDetails(const EQApplicationPacket *app);
void Handle_OP_RecipesFavorite(const EQApplicationPacket *app);
void Handle_OP_RecipesSearch(const EQApplicationPacket *app);
void Handle_OP_ReloadUI(const EQApplicationPacket *app);
void Handle_OP_RemoveBlockedBuffs(const EQApplicationPacket *app);
void Handle_OP_Report(const EQApplicationPacket *app);
void Handle_OP_RequestDuel(const EQApplicationPacket *app);
void Handle_OP_RequestTitles(const EQApplicationPacket *app);
void Handle_OP_RespawnWindow(const EQApplicationPacket *app);
void Handle_OP_Rewind(const EQApplicationPacket *app);
void Handle_OP_RezzAnswer(const EQApplicationPacket *app);
void Handle_OP_Sacrifice(const EQApplicationPacket *app);
void Handle_OP_SafeFallSuccess(const EQApplicationPacket *app);
void Handle_OP_SafePoint(const EQApplicationPacket *app);
void Handle_OP_Save(const EQApplicationPacket *app);
void Handle_OP_SaveOnZoneReq(const EQApplicationPacket *app);
void Handle_OP_SelectTribute(const EQApplicationPacket *app);
void Handle_OP_SenseHeading(const EQApplicationPacket *app);
void Handle_OP_SenseTraps(const EQApplicationPacket *app);
void Handle_OP_SetGuildMOTD(const EQApplicationPacket *app);
void Handle_OP_SetRunMode(const EQApplicationPacket *app);
void Handle_OP_SetServerFilter(const EQApplicationPacket *app);
void Handle_OP_SetStartCity(const EQApplicationPacket *app);
void Handle_OP_SetTitle(const EQApplicationPacket *app);
void Handle_OP_Shielding(const EQApplicationPacket *app);
void Handle_OP_ShopEnd(const EQApplicationPacket *app);
void Handle_OP_ShopPlayerBuy(const EQApplicationPacket *app);
void Handle_OP_ShopPlayerSell(const EQApplicationPacket *app);
void Handle_OP_ShopRequest(const EQApplicationPacket *app);
void Handle_OP_Sneak(const EQApplicationPacket *app);
void Handle_OP_SpawnAppearance(const EQApplicationPacket *app);
void Handle_OP_Split(const EQApplicationPacket *app);
void Handle_OP_Surname(const EQApplicationPacket *app);
void Handle_OP_SwapSpell(const EQApplicationPacket *app);
void Handle_OP_TargetCommand(const EQApplicationPacket *app);
void Handle_OP_TargetMouse(const EQApplicationPacket *app);
void Handle_OP_TaskHistoryRequest(const EQApplicationPacket *app);
void Handle_OP_Taunt(const EQApplicationPacket *app);
void Handle_OP_TestBuff(const EQApplicationPacket *app);
void Handle_OP_TGB(const EQApplicationPacket *app);
void Handle_OP_Track(const EQApplicationPacket *app);
void Handle_OP_TrackTarget(const EQApplicationPacket *app);
void Handle_OP_TrackUnknown(const EQApplicationPacket *app);
void Handle_OP_TradeAcceptClick(const EQApplicationPacket *app);
void Handle_OP_TradeBusy(const EQApplicationPacket *app);
void Handle_OP_Trader(const EQApplicationPacket *app);
void Handle_OP_TraderBuy(const EQApplicationPacket *app);
void Handle_OP_TradeRequest(const EQApplicationPacket *app);
void Handle_OP_TradeRequestAck(const EQApplicationPacket *app);
void Handle_OP_TraderShop(const EQApplicationPacket *app);
void Handle_OP_TradeSkillCombine(const EQApplicationPacket *app);
void Handle_OP_Translocate(const EQApplicationPacket *app);
void Handle_OP_TributeItem(const EQApplicationPacket *app);
void Handle_OP_TributeMoney(const EQApplicationPacket *app);
void Handle_OP_TributeNPC(const EQApplicationPacket *app);
void Handle_OP_TributeToggle(const EQApplicationPacket *app);
void Handle_OP_TributeUpdate(const EQApplicationPacket *app);
void Handle_OP_VetClaimRequest(const EQApplicationPacket *app);
void Handle_OP_VoiceMacroIn(const EQApplicationPacket *app);
void Handle_OP_WearChange(const EQApplicationPacket *app);
void Handle_OP_WhoAllRequest(const EQApplicationPacket *app);
void Handle_OP_XTargetAutoAddHaters(const EQApplicationPacket *app);
void Handle_OP_XTargetRequest(const EQApplicationPacket *app);
void Handle_OP_YellForHelp(const EQApplicationPacket *app);
void Handle_OP_ZoneChange(const EQApplicationPacket *app);
+9 -3
View File
@@ -1547,7 +1547,12 @@ void Client::OPMoveCoin(const EQApplicationPacket* app)
if (from_bucket == &m_pp.platinum_shared)
amount_to_add = 0 - amount_to_take;
database.SetSharedPlatinum(AccountID(),amount_to_add);
database.SetSharedPlatinum(AccountID(),amount_to_add);
}
}
else{
if (to_bucket == &m_pp.platinum_shared || from_bucket == &m_pp.platinum_shared){
this->Message(13, "::: WARNING! ::: SHARED BANK IS DISABLED AND YOUR PLATINUM WILL BE DESTROYED IF YOU PUT IT HERE");
}
}
}
@@ -1580,7 +1585,7 @@ void Client::OPMoveCoin(const EQApplicationPacket* app)
safe_delete(outapp);
}
Save();
SaveCurrency();
}
void Client::OPGMTraining(const EQApplicationPacket *app)
@@ -1715,6 +1720,7 @@ void Client::OPGMTrainSkill(const EQApplicationPacket *app)
}
uint16 skilllevel = GetRawSkill(skill);
if(skilllevel == 0) {
//this is a new skill..
uint16 t_level = SkillTrainLevel(skill, GetClass());
@@ -1724,7 +1730,7 @@ void Client::OPGMTrainSkill(const EQApplicationPacket *app)
}
SetSkill(skill, t_level);
} else {
} else {
switch(skill) {
case SkillBrewing:
case SkillMakePoison:
+84 -182
View File
@@ -149,7 +149,7 @@ Access Levels:
int command_init(void) {
if
(
command_add("resetaa","- Resets a Player's AA in their profile.",200,command_resetaa) ||
command_add("resetaa","- Resets a Player's AA in their profile and refunds spent AA's to unspent, disconnects player.",200,command_resetaa) ||
command_add("qtest","- QueryServ testing command.",255,command_qtest) ||
command_add("bind","- Sets your targets bind spot to their current location",200,command_bind) ||
command_add("sendop","[opcode] - LE's Private test command, leave it alone",200,command_sendop) ||
@@ -225,7 +225,6 @@ int command_init(void) {
command_add("worldshutdown","- Shut down world and all zones",200,command_worldshutdown) ||
command_add("sendzonespawns","- Refresh spawn list for all clients in zone",150,command_sendzonespawns) ||
command_add("dbspawn2","[spawngroup] [respawn] [variance] - Spawn an NPC from a predefined row in the spawn2 table",100,command_dbspawn2) ||
command_add("copychar","[character name] [new character] [new account id] - Create a copy of a character",100,command_copychar) ||
command_add("shutdown","- Shut this zone process down",150,command_shutdown) ||
command_add("delacct","[accountname] - Delete an account",150,command_delacct) ||
command_add("setpass","[accountname] [password] - Set local password for accountname",150,command_setpass) ||
@@ -258,12 +257,11 @@ int command_init(void) {
command_add("dbspawn",nullptr,0,command_npctypespawn) ||
command_add("heal","- Completely heal your target",10,command_heal) ||
command_add("appearance","[type] [value] - Send an appearance packet for you or your target",150,command_appearance) ||
command_add("charbackup","[list/restore] - Query or restore character backups",150,command_charbackup) ||
command_add("nukeitem","[itemid] - Remove itemid from your player target's inventory",150,command_nukeitem) ||
command_add("peekinv","[worn/cursor/inv/bank/trade/trib/all] - Print out contents of your player target's inventory",100,command_peekinv) ||
command_add("findnpctype","[search criteria] - Search database NPC types",100,command_findnpctype) ||
command_add("findzone","[search criteria] - Search database zones",100,command_findzone) ||
command_add("fz",nullptr,100,command_findzone) ||
command_add("fz",nullptr,100, command_findzone) ||
command_add("viewnpctype","[npctype id] - Show info about an npctype",100,command_viewnpctype) ||
command_add("reloadstatic","- Reload Static Zone Data",150,command_reloadstatic) ||
command_add("reloadquest"," - Clear quest cache (any argument causes it to also stop all timers)",150,command_reloadqst) ||
@@ -405,7 +403,6 @@ int command_init(void) {
command_add("guildapprove","[guildapproveid] - Approve a guild with specified ID (guild creator receives the id)",0,command_guildapprove) ||
command_add("guildlist","[guildapproveid] - Lists character names who have approved the guild specified by the approve id",0,command_guildlist) ||
command_add("altactivate", "[argument] - activates alternate advancement abilities, use altactivate help for more information", 0, command_altactivate) ||
command_add("refundaa", "- Refunds your target's AA points, will disconnect them in the process as well.", 100, command_refundaa) ||
#ifdef BOTS
command_add("bot","- Type \"#bot help\" to the see the list of available commands for bots.", 0, command_bot) ||
@@ -2156,8 +2153,8 @@ void command_worldshutdown(Client *c, const Seperator *sep)
uint32 interval=0;
if (worldserver.Connected()) {
if(sep->IsNumber(1) && sep->IsNumber(2) && ((time=atoi(sep->arg[1]))>0) && ((interval=atoi(sep->arg[2]))>0)) {
worldserver.SendEmoteMessage(0,0,15,"<SYSTEMWIDE MESSAGE>:SYSTEM MSG:World coming down in %i seconds, everyone log out before this time.",time);
c->Message(0, "Sending shutdown packet now, World will shutdown in: %i Seconds with an interval of: %i",time,interval);
worldserver.SendEmoteMessage(0,0,15,"<SYSTEMWIDE MESSAGE>:SYSTEM MSG:World coming down in %i minutes, everyone log out before this time.", (time / 60 ));
c->Message(0, "Sending shutdown packet now, World will shutdown in: %i minutes with an interval of: %i seconds", (time / 60), interval);
ServerPacket* pack = new ServerPacket(ServerOP_ShutdownAll,sizeof(WorldShutDown_Struct));
WorldShutDown_Struct* wsd = (WorldShutDown_Struct*)pack->pBuffer;
wsd->time=time*1000;
@@ -2226,28 +2223,6 @@ void command_dbspawn2(Client *c, const Seperator *sep)
}
}
void command_copychar(Client *c, const Seperator *sep)
{
if(sep->arg[1][0]==0 || sep->arg[2][0] == 0 || sep->arg[3][0] == 0)
c->Message(0, "Usage: #copychar [character name] [new character] [new account id]");
//CheckUsedName.... TRUE=No Char, FALSE=Char/Error
//If there is no source...
else if (database.CheckUsedName((char*)sep->arg[1])) {
c->Message(0, "Source character not found!");
}
else {
//If there is a name is not used....
if (database.CheckUsedName((char*) sep->arg[2])) {
if (!database.CopyCharacter((char*) sep->arg[1], (char*) sep->arg[2], atoi(sep->arg[3])))
c->Message(0, "Character copy operation failed!");
else
c->Message(0, "Character copy complete.");
}
else
c->Message(0, "Target character already exists!");
}
}
void command_shutdown(Client *c, const Seperator *sep)
{
CatchSignal(2);
@@ -2422,8 +2397,8 @@ void command_showskills(Client *c, const Seperator *sep)
c->Message(0, "Skills for %s", t->GetName());
for (SkillUseTypes i=Skill1HBlunt; i <= HIGHEST_SKILL; i=(SkillUseTypes)(i+1))
c->Message(0, "Skill [%d] is at [%d]", i, t->GetSkill(i));
}
c->Message(0, "Skill [%d] is at [%d] - %u", i, t->GetSkill(i), t->GetRawSkill(i));
}
void command_findspell(Client *c, const Seperator *sep)
{
@@ -2490,14 +2465,14 @@ void command_castspell(Client *c, const Seperator *sep)
else
if (c->GetTarget() == 0)
if(c->Admin() >= commandInstacast)
c->SpellFinished(spellid, 0, 10, 0, -1, spells[spellid].ResistDiff);
c->SpellFinished(spellid, 0, USE_ITEM_SPELL_SLOT, 0, -1, spells[spellid].ResistDiff);
else
c->CastSpell(spellid, 0, 10, 0);
c->CastSpell(spellid, 0, USE_ITEM_SPELL_SLOT, 0);
else
if(c->Admin() >= commandInstacast)
c->SpellFinished(spellid, c->GetTarget(), 10, 0, -1, spells[spellid].ResistDiff);
else
c->CastSpell(spellid, c->GetTarget()->GetID(), 10, 0);
c->CastSpell(spellid, c->GetTarget()->GetID(), USE_ITEM_SPELL_SLOT, 0);
}
}
@@ -2789,85 +2764,6 @@ void command_appearance(Client *c, const Seperator *sep)
}
}
void command_charbackup(Client *c, const Seperator *sep)
{
char errbuf[MYSQL_ERRMSG_SIZE];
char *query = 0;
MYSQL_RES* result;
MYSQL_ROW row;
if (strcasecmp(sep->arg[1], "list") == 0) {
uint32 charid = 0;
if (sep->IsNumber(2))
charid = atoi(sep->arg[2]);
else
database.GetAccountIDByChar(sep->arg[2], &charid);
if (charid) {
if (database.RunQuery(query, MakeAnyLenString(&query,
"Select id, backupreason, charid, account_id, zoneid, DATE_FORMAT(ts, '%%m/%%d/%%Y %%H:%%i:%%s') "
" from character_backup where charid=%u", charid), errbuf, &result)) {
safe_delete(query);
uint32 x = 0;
while ((row = mysql_fetch_row(result))) {
c->Message(0, " %u: %s, %s (%u), reason=%u", atoi(row[0]), row[5], database.GetZoneName(atoi(row[4])), atoi(row[4]), atoi(row[1]));
x++;
}
c->Message(0, " %u backups found.", x);
mysql_free_result(result);
}
else {
c->Message(13, "Query error: '%s' %s", query, errbuf);
safe_delete(query);
}
}
else
c->Message(0, "Usage: #charbackup list [char name/id]");
}
else if (strcasecmp(sep->arg[1], "restore") == 0) {
uint32 charid = 0;
if (sep->IsNumber(2))
charid = atoi(sep->arg[2]);
else
database.GetAccountIDByChar(sep->arg[2], &charid);
if (charid && sep->IsNumber(3)) {
uint32 cbid = atoi(sep->arg[3]);
if (database.RunQuery(query, MakeAnyLenString(&query,
"Insert into character_backup (backupreason, charid, account_id, name, profile, level, class, x, y, z, zoneid, alt_adv) "
" select 1, id, account_id, name, profile, level, class, x, y, z, zoneid, alt_adv from character_ where id=%u", charid), errbuf)) {
if (database.RunQuery(query, MakeAnyLenString(&query,
"update character_ inner join character_backup on character_.id = character_backup.charid "
" set character_.name = character_backup.name, "
" character_.profile = character_backup.profile, "
" character_.level = character_backup.level, "
" character_.class = character_backup.class, "
" character_.x = character_backup.x, "
" character_.y = character_backup.y, "
" character_.z = character_backup.z, "
" character_.zoneid = character_backup.zoneid "
" where character_backup.charid=%u and character_backup.id=%u", charid, cbid), errbuf)) {
safe_delete(query);
c->Message(0, "Character restored.");
}
else {
c->Message(13, "Query error: '%s' %s", query, errbuf);
safe_delete(query);
}
}
else {
c->Message(13, "Query error: '%s' %s", query, errbuf);
safe_delete(query);
}
}
else
c->Message(0, "Usage: #charbackup list [char name/id]");
}
else {
c->Message(0, "#charbackup sub-commands:");
c->Message(0, " list [char name/id]");
c->Message(0, " restore [char name/id] [backup#]");
}
}
void command_nukeitem(Client *c, const Seperator *sep)
{
int numitems, itemid;
@@ -6225,13 +6121,13 @@ void command_setcrystals(Client *c, const Seperator *sep)
{
t->SetRadiantCrystals(atoi(sep->arg[2]));
t->SendCrystalCounts();
t->Save();
t->SaveCurrency();
}
else if(!strcasecmp(sep->arg[1], "ebon"))
{
t->SetEbonCrystals(atoi(sep->arg[2]));
t->SendCrystalCounts();
t->Save();
t->SaveCurrency();
}
else
{
@@ -6258,36 +6154,49 @@ void command_stun(Client *c, const Seperator *sep)
c->Message(0, "Usage: #stun [duration]");
}
void command_ban(Client *c, const Seperator *sep)
{
char errbuf[MYSQL_ERRMSG_SIZE];
char *query = 0;
MYSQL_RES *result;
MYSQL_ROW row;
if(sep->arg[1][0] == 0)
if(sep->arg[1][0] == 0 || sep->arg[2][0] == 0)
{
c->Message(0, "Usage: #ban [charname]");
c->Message(0, "Usage: #ban <charname> <message>");
}
else
{
database.RunQuery(query, MakeAnyLenString(&query, "SELECT account_id from character_ where name = '%s'", sep->arg[1]), errbuf, &result);
if(query)
{
safe_delete_array(query);
auto account_id = database.GetAccountIDByChar(sep->arg[1]);
std::string message;
int i = 2;
while(1) {
if(sep->arg[i][0] == 0) {
break;
}
if(message.length() > 0) {
message.push_back(' ');
}
message += sep->arg[i];
++i;
}
if(mysql_num_rows(result))
{
row = mysql_fetch_row(result);
database.RunQuery(query, MakeAnyLenString(&query, "UPDATE account set status = -2 where id = %i", atoi(row[0])), errbuf, 0);
c->Message(13,"Account number %i with the character %s has been banned.", atoi(row[0]), sep->arg[1]);
if(message.length() == 0) {
c->Message(0, "Usage: #ban <charname> <message>");
return;
}
ServerPacket* pack = new ServerPacket(ServerOP_FlagUpdate, 6);
*((uint32*) pack->pBuffer) = atoi(row[0]);
*((int16*) &pack->pBuffer[4]) = -2;
worldserver.SendPacket(pack);
safe_delete(pack);
if(account_id > 0)
{
database.RunQuery(query, MakeAnyLenString(&query, "UPDATE account set status = -2, ban_reason = '%s' where id = %i", EscapeString(message).c_str(), account_id), errbuf, 0);
c->Message(13, "Account number %i with the character %s has been banned with message: \"%s\"", account_id, sep->arg[1], message.c_str());
ServerPacket pack(ServerOP_FlagUpdate, 6);
*((uint32*)&pack.pBuffer[0]) = account_id;
*((int16*)&pack.pBuffer[4]) = -2;
worldserver.SendPacket(&pack);
Client *client = nullptr;
client = entity_list.GetClientByName(sep->arg[1]);
@@ -6297,25 +6206,20 @@ void command_ban(Client *c, const Seperator *sep)
}
else
{
ServerPacket* pack = new ServerPacket(ServerOP_KickPlayer, sizeof(ServerKickPlayer_Struct));
ServerKickPlayer_Struct* skp = (ServerKickPlayer_Struct*) pack->pBuffer;
ServerPacket pack(ServerOP_KickPlayer, sizeof(ServerKickPlayer_Struct));
ServerKickPlayer_Struct* skp = (ServerKickPlayer_Struct*)pack.pBuffer;
strcpy(skp->adminname, c->GetName());
strcpy(skp->name, sep->arg[1]);
skp->adminrank = c->Admin();
worldserver.SendPacket(pack);
safe_delete(pack);
worldserver.SendPacket(&pack);
}
mysql_free_result(result);
}
else
{
c->Message(13,"Character does not exist.");
}
if(query)
{
safe_delete_array(query);
c->Message(13, "Character does not exist.");
}
safe_delete_array(query);
}
}
@@ -6325,7 +6229,7 @@ void command_suspend(Client *c, const Seperator *sep)
char *query = nullptr;
if((sep->arg[1][0] == 0) || (sep->arg[2][0] == 0))
c->Message(0, "Usage: #suspend <charname> <days> (Specify 0 days to lift the suspension immediately)");
c->Message(0, "Usage: #suspend <charname> <days>(Specify 0 days to lift the suspension immediately) <message>");
else
{
int Duration = atoi(sep->arg[2]);
@@ -6333,22 +6237,40 @@ void command_suspend(Client *c, const Seperator *sep)
if(Duration < 0)
Duration = 0;
char *EscName = new char[strlen(sep->arg[1]) * 2 + 1];
std::string message;
if(Duration > 0) {
int i = 3;
while(1) {
if(sep->arg[i][0] == 0) {
break;
}
database.DoEscapeString(EscName, sep->arg[1], strlen(sep->arg[1]));
if(message.length() > 0) {
message.push_back(' ');
}
message += sep->arg[i];
++i;
}
if(message.length() == 0) {
c->Message(0, "Usage: #suspend <charname> <days>(Specify 0 days to lift the suspension immediately) <message>");
return;
}
}
int AccountID;
if((AccountID = database.GetAccountIDByChar(EscName)) > 0)
if((AccountID = database.GetAccountIDByChar(sep->arg[1])) > 0)
{
database.RunQuery(query, MakeAnyLenString(&query, "UPDATE `account` SET `suspendeduntil` = DATE_ADD(NOW(), INTERVAL %i DAY)"
" WHERE `id` = %i", Duration, AccountID), errbuf, 0);
database.RunQuery(query, MakeAnyLenString(&query, "UPDATE `account` SET `suspendeduntil` = DATE_ADD(NOW(), INTERVAL %i DAY), "
"suspend_reason = '%s' WHERE `id` = %i", Duration, EscapeString(message).c_str(), AccountID), errbuf, 0);
if(Duration)
c->Message(13,"Account number %i with the character %s has been temporarily suspended for %i day(s).", AccountID, sep->arg[1],
Duration);
c->Message(13, "Account number %i with the character %s has been temporarily suspended for %i day(s) with the message: \"%s\"", AccountID, sep->arg[1],
Duration, message.c_str());
else
c->Message(13,"Account number %i with the character %s is no longer suspended.", AccountID, sep->arg[1]);
c->Message(13, "Account number %i with the character %s is no longer suspended.", AccountID, sep->arg[1]);
safe_delete_array(query);
@@ -6358,22 +6280,20 @@ void command_suspend(Client *c, const Seperator *sep)
BannedClient->WorldKick();
else
{
ServerPacket* pack = new ServerPacket(ServerOP_KickPlayer, sizeof(ServerKickPlayer_Struct));
ServerKickPlayer_Struct* sks = (ServerKickPlayer_Struct*) pack->pBuffer;
ServerPacket pack(ServerOP_KickPlayer, sizeof(ServerKickPlayer_Struct));
ServerKickPlayer_Struct* sks = (ServerKickPlayer_Struct*)pack.pBuffer;
strn0cpy(sks->adminname, c->GetName(), sizeof(sks->adminname));
strn0cpy(sks->name, sep->arg[1], sizeof(sks->name));
sks->adminrank = c->Admin();
worldserver.SendPacket(pack);
safe_delete(pack);
worldserver.SendPacket(&pack);
}
} else
c->Message(13,"Character does not exist.");
safe_delete_array(EscName);
}
else {
c->Message(13, "Character does not exist.");
}
}
}
@@ -7761,7 +7681,7 @@ void Client::Undye() {
SendWearChange(cur_slot);
}
Save(0);
database.DeleteCharacterDye(this->CharacterID());
}
void command_undye(Client *c, const Seperator *sep)
@@ -8613,25 +8533,6 @@ void command_altactivate(Client *c, const Seperator *sep){
}
}
void command_refundaa(Client *c, const Seperator *sep){
Client* refundee = nullptr;
if(c) {
if(c->GetTarget()){
if(c->GetTarget()->IsClient())
refundee = c->GetTarget()->CastToClient();
else
c->Message(0, "Your target must be a client.");
}
else{
c->Message(0, "You must have a target selected.");
}
if(refundee) {
refundee->RefundAA();
}
}
}
void command_traindisc(Client *c, const Seperator *sep)
{
uint8 max_level, min_level;
@@ -8687,6 +8588,7 @@ void command_traindisc(Client *c, const Seperator *sep)
break; //continue the 1st loop
} else if(t->GetPP().disciplines.values[r] == 0) {
t->GetPP().disciplines.values[r] = curspell;
database.SaveCharacterDisc(c->CharacterID(), r, curspell);
t->SendDisciplineUpdate();
t->Message(0, "You have learned a new discipline!");
count++; //success counter
-2
View File
@@ -125,7 +125,6 @@ void command_worldshutdown(Client *c, const Seperator *sep);
void command_sendzonespawns(Client *c, const Seperator *sep);
void command_zsave(Client *c, const Seperator *sep);
void command_dbspawn2(Client *c, const Seperator *sep);
void command_copychar(Client *c, const Seperator *sep);
void command_shutdown(Client *c, const Seperator *sep);
void command_delacct(Client *c, const Seperator *sep);
void command_setpass(Client *c, const Seperator *sep);
@@ -151,7 +150,6 @@ void command_texture(Client *c, const Seperator *sep);
void command_npctypespawn(Client *c, const Seperator *sep);
void command_heal(Client *c, const Seperator *sep);
void command_appearance(Client *c, const Seperator *sep);
void command_charbackup(Client *c, const Seperator *sep);
void command_nukeitem(Client *c, const Seperator *sep);
void command_peekinv(Client *c, const Seperator *sep);
void command_findnpctype(Client *c, const Seperator *sep);
+5
View File
@@ -17,6 +17,10 @@
#define _NPCPET(x) (x && x->IsNPC() && x->CastToMob()->GetOwner() && x->CastToMob()->GetOwner()->IsNPC())
#define _BECOMENPCPET(x) (x && x->CastToMob()->GetOwner() && x->CastToMob()->GetOwner()->IsClient() && x->CastToMob()->GetOwner()->CastToClient()->IsBecomeNPC())
#define USE_ITEM_SPELL_SLOT 10
#define POTION_BELT_SPELL_SLOT 11
#define DISCIPLINE_SPELL_SLOT 10
#define ABILITY_SPELL_SLOT 9
//LOS Parameters:
#define HEAD_POSITION 0.9f //ratio of GetSize() where NPCs see from
@@ -290,6 +294,7 @@ struct StatBonuses {
int16 ResistFearChance; //i
bool Fearless; //i
bool IsFeared; //i
bool IsBlind; //i
int16 StunResist; //i
int16 MeleeSkillCheck; //i
uint8 MeleeSkillCheckSkill;

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