Move core/realm files to new subdirectory
--HG-- branch : trunk rename : src/framework/CMakeLists.txt => src/server/framework/CMakeLists.txt rename : src/framework/Dynamic/FactoryHolder.h => src/server/framework/Dynamic/FactoryHolder.h rename : src/framework/Dynamic/ObjectRegistry.h => src/server/framework/Dynamic/ObjectRegistry.h rename : src/framework/GameSystem/Grid.h => src/server/framework/GameSystem/Grid.h rename : src/framework/GameSystem/GridLoader.h => src/server/framework/GameSystem/GridLoader.h rename : src/framework/GameSystem/GridRefManager.h => src/server/framework/GameSystem/GridRefManager.h rename : src/framework/GameSystem/GridReference.h => src/server/framework/GameSystem/GridReference.h rename : src/framework/GameSystem/NGrid.h => src/server/framework/GameSystem/NGrid.h rename : src/framework/GameSystem/TypeContainer.h => src/server/framework/GameSystem/TypeContainer.h rename : src/framework/GameSystem/TypeContainerFunctions.h => src/server/framework/GameSystem/TypeContainerFunctions.h rename : src/framework/GameSystem/TypeContainerFunctionsPtr.h => src/server/framework/GameSystem/TypeContainerFunctionsPtr.h rename : src/framework/GameSystem/TypeContainerVisitor.h => src/server/framework/GameSystem/TypeContainerVisitor.h rename : src/framework/Network/SocketDefines.h => src/server/framework/Network/SocketDefines.h rename : src/framework/Platform/CompilerDefs.h => src/server/framework/Platform/CompilerDefs.h rename : src/framework/Platform/Define.h => src/server/framework/Platform/Define.h rename : src/framework/Policies/CreationPolicy.h => src/server/framework/Policies/CreationPolicy.h rename : src/framework/Policies/ObjectLifeTime.cpp => src/server/framework/Policies/ObjectLifeTime.cpp rename : src/framework/Policies/ObjectLifeTime.h => src/server/framework/Policies/ObjectLifeTime.h rename : src/framework/Policies/Singleton.h => src/server/framework/Policies/Singleton.h rename : src/framework/Policies/SingletonImp.h => src/server/framework/Policies/SingletonImp.h rename : src/framework/Policies/ThreadingModel.h => src/server/framework/Policies/ThreadingModel.h rename : src/framework/Utilities/ByteConverter.h => src/server/framework/Utilities/ByteConverter.h rename : src/framework/Utilities/Callback.h => src/server/framework/Utilities/Callback.h rename : src/framework/Utilities/CountedReference/Reference.h => src/server/framework/Utilities/CountedReference/Reference.h rename : src/framework/Utilities/CountedReference/ReferenceHolder.h => src/server/framework/Utilities/CountedReference/ReferenceHolder.h rename : src/framework/Utilities/CountedReference/ReferenceImpl.h => src/server/framework/Utilities/CountedReference/ReferenceImpl.h rename : src/framework/Utilities/EventProcessor.cpp => src/server/framework/Utilities/EventProcessor.cpp rename : src/framework/Utilities/EventProcessor.h => src/server/framework/Utilities/EventProcessor.h rename : src/framework/Utilities/LinkedList.h => src/server/framework/Utilities/LinkedList.h rename : src/framework/Utilities/LinkedReference/RefManager.h => src/server/framework/Utilities/LinkedReference/RefManager.h rename : src/framework/Utilities/LinkedReference/Reference.h => src/server/framework/Utilities/LinkedReference/Reference.h rename : src/framework/Utilities/TypeList.h => src/server/framework/Utilities/TypeList.h rename : src/framework/Utilities/UnorderedMap.h => src/server/framework/Utilities/UnorderedMap.h rename : src/game/AccountMgr.cpp => src/server/game/AccountMgr.cpp rename : src/game/AccountMgr.h => src/server/game/AccountMgr.h rename : src/game/AchievementMgr.cpp => src/server/game/AchievementMgr.cpp rename : src/game/AchievementMgr.h => src/server/game/AchievementMgr.h rename : src/game/AddonHandler.cpp => src/server/game/AddonHandler.cpp rename : src/game/AddonHandler.h => src/server/game/AddonHandler.h rename : src/game/AddonMgr.cpp => src/server/game/AddonMgr.cpp rename : src/game/AddonMgr.h => src/server/game/AddonMgr.h rename : src/game/ArenaTeam.cpp => src/server/game/ArenaTeam.cpp rename : src/game/ArenaTeam.h => src/server/game/ArenaTeam.h rename : src/game/ArenaTeamHandler.cpp => src/server/game/ArenaTeamHandler.cpp rename : src/game/AuctionHouseBot.cpp => src/server/game/AuctionHouseBot.cpp rename : src/game/AuctionHouseBot.h => src/server/game/AuctionHouseBot.h rename : src/game/AuctionHouseHandler.cpp => src/server/game/AuctionHouseHandler.cpp rename : src/game/AuctionHouseMgr.cpp => src/server/game/AuctionHouseMgr.cpp rename : src/game/AuctionHouseMgr.h => src/server/game/AuctionHouseMgr.h rename : src/game/Bag.cpp => src/server/game/Bag.cpp rename : src/game/Bag.h => src/server/game/Bag.h rename : src/game/BattleGround.cpp => src/server/game/BattleGround.cpp rename : src/game/BattleGround.h => src/server/game/BattleGround.h rename : src/game/BattleGroundAA.cpp => src/server/game/BattleGroundAA.cpp rename : src/game/BattleGroundAA.h => src/server/game/BattleGroundAA.h rename : src/game/BattleGroundAB.cpp => src/server/game/BattleGroundAB.cpp rename : src/game/BattleGroundAB.h => src/server/game/BattleGroundAB.h rename : src/game/BattleGroundAV.cpp => src/server/game/BattleGroundAV.cpp rename : src/game/BattleGroundAV.h => src/server/game/BattleGroundAV.h rename : src/game/BattleGroundBE.cpp => src/server/game/BattleGroundBE.cpp rename : src/game/BattleGroundBE.h => src/server/game/BattleGroundBE.h rename : src/game/BattleGroundDS.cpp => src/server/game/BattleGroundDS.cpp rename : src/game/BattleGroundDS.h => src/server/game/BattleGroundDS.h rename : src/game/BattleGroundEY.cpp => src/server/game/BattleGroundEY.cpp rename : src/game/BattleGroundEY.h => src/server/game/BattleGroundEY.h rename : src/game/BattleGroundHandler.cpp => src/server/game/BattleGroundHandler.cpp rename : src/game/BattleGroundIC.cpp => src/server/game/BattleGroundIC.cpp rename : src/game/BattleGroundIC.h => src/server/game/BattleGroundIC.h rename : src/game/BattleGroundMgr.cpp => src/server/game/BattleGroundMgr.cpp rename : src/game/BattleGroundMgr.h => src/server/game/BattleGroundMgr.h rename : src/game/BattleGroundNA.cpp => src/server/game/BattleGroundNA.cpp rename : src/game/BattleGroundNA.h => src/server/game/BattleGroundNA.h rename : src/game/BattleGroundRB.cpp => src/server/game/BattleGroundRB.cpp rename : src/game/BattleGroundRB.h => src/server/game/BattleGroundRB.h rename : src/game/BattleGroundRL.cpp => src/server/game/BattleGroundRL.cpp rename : src/game/BattleGroundRL.h => src/server/game/BattleGroundRL.h rename : src/game/BattleGroundRV.cpp => src/server/game/BattleGroundRV.cpp rename : src/game/BattleGroundRV.h => src/server/game/BattleGroundRV.h rename : src/game/BattleGroundSA.cpp => src/server/game/BattleGroundSA.cpp rename : src/game/BattleGroundSA.h => src/server/game/BattleGroundSA.h rename : src/game/BattleGroundWS.cpp => src/server/game/BattleGroundWS.cpp rename : src/game/BattleGroundWS.h => src/server/game/BattleGroundWS.h rename : src/game/CMakeLists.txt => src/server/game/CMakeLists.txt rename : src/game/Calendar.cpp => src/server/game/Calendar.cpp rename : src/game/Calendar.h => src/server/game/Calendar.h rename : src/game/CalendarHandler.cpp => src/server/game/CalendarHandler.cpp rename : src/game/Cell.h => src/server/game/Cell.h rename : src/game/CellImpl.h => src/server/game/CellImpl.h rename : src/game/Channel.cpp => src/server/game/Channel.cpp rename : src/game/Channel.h => src/server/game/Channel.h rename : src/game/ChannelHandler.cpp => src/server/game/ChannelHandler.cpp rename : src/game/ChannelMgr.cpp => src/server/game/ChannelMgr.cpp rename : src/game/ChannelMgr.h => src/server/game/ChannelMgr.h rename : src/game/CharacterHandler.cpp => src/server/game/CharacterHandler.cpp rename : src/game/Chat.cpp => src/server/game/Chat.cpp rename : src/game/Chat.h => src/server/game/Chat.h rename : src/game/ChatHandler.cpp => src/server/game/ChatHandler.cpp rename : src/game/CombatAI.cpp => src/server/game/CombatAI.cpp rename : src/game/CombatAI.h => src/server/game/CombatAI.h rename : src/game/CombatHandler.cpp => src/server/game/CombatHandler.cpp rename : src/game/ConditionMgr.cpp => src/server/game/ConditionMgr.cpp rename : src/game/ConditionMgr.h => src/server/game/ConditionMgr.h rename : src/game/ConfusedMovementGenerator.cpp => src/server/game/ConfusedMovementGenerator.cpp rename : src/game/ConfusedMovementGenerator.h => src/server/game/ConfusedMovementGenerator.h rename : src/game/Corpse.cpp => src/server/game/Corpse.cpp rename : src/game/Corpse.h => src/server/game/Corpse.h rename : src/game/Creature.cpp => src/server/game/Creature.cpp rename : src/game/Creature.h => src/server/game/Creature.h rename : src/game/CreatureAI.cpp => src/server/game/CreatureAI.cpp rename : src/game/CreatureAI.h => src/server/game/CreatureAI.h rename : src/game/CreatureAIFactory.h => src/server/game/CreatureAIFactory.h rename : src/game/CreatureAIImpl.h => src/server/game/CreatureAIImpl.h rename : src/game/CreatureAIRegistry.cpp => src/server/game/CreatureAIRegistry.cpp rename : src/game/CreatureAIRegistry.h => src/server/game/CreatureAIRegistry.h rename : src/game/CreatureAISelector.cpp => src/server/game/CreatureAISelector.cpp rename : src/game/CreatureAISelector.h => src/server/game/CreatureAISelector.h rename : src/game/CreatureEventAI.cpp => src/server/game/CreatureEventAI.cpp rename : src/game/CreatureEventAI.h => src/server/game/CreatureEventAI.h rename : src/game/CreatureEventAIMgr.cpp => src/server/game/CreatureEventAIMgr.cpp rename : src/game/CreatureEventAIMgr.h => src/server/game/CreatureEventAIMgr.h rename : src/game/CreatureGroups.cpp => src/server/game/CreatureGroups.cpp rename : src/game/CreatureGroups.h => src/server/game/CreatureGroups.h rename : src/game/DBCEnums.h => src/server/game/DBCEnums.h rename : src/game/DBCStores.cpp => src/server/game/DBCStores.cpp rename : src/game/DBCStores.h => src/server/game/DBCStores.h rename : src/game/DBCStructure.h => src/server/game/DBCStructure.h rename : src/game/DBCfmt.h => src/server/game/DBCfmt.h rename : src/game/Debugcmds.cpp => src/server/game/Debugcmds.cpp rename : src/game/DestinationHolder.cpp => src/server/game/DestinationHolder.cpp rename : src/game/DestinationHolder.h => src/server/game/DestinationHolder.h rename : src/game/DestinationHolderImp.h => src/server/game/DestinationHolderImp.h rename : src/game/DuelHandler.cpp => src/server/game/DuelHandler.cpp rename : src/game/DynamicObject.cpp => src/server/game/DynamicObject.cpp rename : src/game/DynamicObject.h => src/server/game/DynamicObject.h rename : src/game/FleeingMovementGenerator.cpp => src/server/game/FleeingMovementGenerator.cpp rename : src/game/FleeingMovementGenerator.h => src/server/game/FleeingMovementGenerator.h rename : src/game/FollowerRefManager.h => src/server/game/FollowerRefManager.h rename : src/game/FollowerReference.cpp => src/server/game/FollowerReference.cpp rename : src/game/FollowerReference.h => src/server/game/FollowerReference.h rename : src/game/Formulas.h => src/server/game/Formulas.h rename : src/game/GameEventMgr.cpp => src/server/game/GameEventMgr.cpp rename : src/game/GameEventMgr.h => src/server/game/GameEventMgr.h rename : src/game/GameObject.cpp => src/server/game/GameObject.cpp rename : src/game/GameObject.h => src/server/game/GameObject.h rename : src/game/GlobalEvents.cpp => src/server/game/GlobalEvents.cpp rename : src/game/GlobalEvents.h => src/server/game/GlobalEvents.h rename : src/game/GossipDef.cpp => src/server/game/GossipDef.cpp rename : src/game/GossipDef.h => src/server/game/GossipDef.h rename : src/game/GridDefines.h => src/server/game/GridDefines.h rename : src/game/GridNotifiers.cpp => src/server/game/GridNotifiers.cpp rename : src/game/GridNotifiers.h => src/server/game/GridNotifiers.h rename : src/game/GridNotifiersImpl.h => src/server/game/GridNotifiersImpl.h rename : src/game/GridStates.cpp => src/server/game/GridStates.cpp rename : src/game/GridStates.h => src/server/game/GridStates.h rename : src/game/Group.cpp => src/server/game/Group.cpp rename : src/game/Group.h => src/server/game/Group.h rename : src/game/GroupHandler.cpp => src/server/game/GroupHandler.cpp rename : src/game/GroupRefManager.h => src/server/game/GroupRefManager.h rename : src/game/GroupReference.cpp => src/server/game/GroupReference.cpp rename : src/game/GroupReference.h => src/server/game/GroupReference.h rename : src/game/GuardAI.cpp => src/server/game/GuardAI.cpp rename : src/game/GuardAI.h => src/server/game/GuardAI.h rename : src/game/Guild.cpp => src/server/game/Guild.cpp rename : src/game/Guild.h => src/server/game/Guild.h rename : src/game/GuildHandler.cpp => src/server/game/GuildHandler.cpp rename : src/game/HomeMovementGenerator.cpp => src/server/game/HomeMovementGenerator.cpp rename : src/game/HomeMovementGenerator.h => src/server/game/HomeMovementGenerator.h rename : src/game/HostileRefManager.cpp => src/server/game/HostileRefManager.cpp rename : src/game/HostileRefManager.h => src/server/game/HostileRefManager.h rename : src/game/IdleMovementGenerator.cpp => src/server/game/IdleMovementGenerator.cpp rename : src/game/IdleMovementGenerator.h => src/server/game/IdleMovementGenerator.h rename : src/game/InstanceData.cpp => src/server/game/InstanceData.cpp rename : src/game/InstanceData.h => src/server/game/InstanceData.h rename : src/game/InstanceSaveMgr.cpp => src/server/game/InstanceSaveMgr.cpp rename : src/game/InstanceSaveMgr.h => src/server/game/InstanceSaveMgr.h rename : src/game/Item.cpp => src/server/game/Item.cpp rename : src/game/Item.h => src/server/game/Item.h rename : src/game/ItemEnchantmentMgr.cpp => src/server/game/ItemEnchantmentMgr.cpp rename : src/game/ItemEnchantmentMgr.h => src/server/game/ItemEnchantmentMgr.h rename : src/game/ItemHandler.cpp => src/server/game/ItemHandler.cpp rename : src/game/ItemPrototype.h => src/server/game/ItemPrototype.h rename : src/game/LFG.h => src/server/game/LFG.h rename : src/game/LFGHandler.cpp => src/server/game/LFGHandler.cpp rename : src/game/LFGMgr.cpp => src/server/game/LFGMgr.cpp rename : src/game/LFGMgr.h => src/server/game/LFGMgr.h rename : src/game/Language.h => src/server/game/Language.h rename : src/game/Level0.cpp => src/server/game/Level0.cpp rename : src/game/Level1.cpp => src/server/game/Level1.cpp rename : src/game/Level2.cpp => src/server/game/Level2.cpp rename : src/game/Level3.cpp => src/server/game/Level3.cpp rename : src/game/LootHandler.cpp => src/server/game/LootHandler.cpp rename : src/game/LootMgr.cpp => src/server/game/LootMgr.cpp rename : src/game/LootMgr.h => src/server/game/LootMgr.h rename : src/game/Mail.cpp => src/server/game/Mail.cpp rename : src/game/Mail.h => src/server/game/Mail.h rename : src/game/Map.cpp => src/server/game/Map.cpp rename : src/game/Map.h => src/server/game/Map.h rename : src/game/MapInstanced.cpp => src/server/game/MapInstanced.cpp rename : src/game/MapInstanced.h => src/server/game/MapInstanced.h rename : src/game/MapManager.cpp => src/server/game/MapManager.cpp rename : src/game/MapManager.h => src/server/game/MapManager.h rename : src/game/MapRefManager.h => src/server/game/MapRefManager.h rename : src/game/MapReference.h => src/server/game/MapReference.h rename : src/game/MapUpdater.cpp => src/server/game/MapUpdater.cpp rename : src/game/MapUpdater.h => src/server/game/MapUpdater.h rename : src/game/MiscHandler.cpp => src/server/game/MiscHandler.cpp rename : src/game/MotionMaster.cpp => src/server/game/MotionMaster.cpp rename : src/game/MotionMaster.h => src/server/game/MotionMaster.h rename : src/game/MovementGenerator.cpp => src/server/game/MovementGenerator.cpp rename : src/game/MovementGenerator.h => src/server/game/MovementGenerator.h rename : src/game/MovementGeneratorImpl.h => src/server/game/MovementGeneratorImpl.h rename : src/game/MovementHandler.cpp => src/server/game/MovementHandler.cpp rename : src/game/NPCHandler.cpp => src/server/game/NPCHandler.cpp rename : src/game/NPCHandler.h => src/server/game/NPCHandler.h rename : src/game/Object.cpp => src/server/game/Object.cpp rename : src/game/Object.h => src/server/game/Object.h rename : src/game/ObjectAccessor.cpp => src/server/game/ObjectAccessor.cpp rename : src/game/ObjectAccessor.h => src/server/game/ObjectAccessor.h rename : src/game/ObjectDefines.h => src/server/game/ObjectDefines.h rename : src/game/ObjectGridLoader.cpp => src/server/game/ObjectGridLoader.cpp rename : src/game/ObjectGridLoader.h => src/server/game/ObjectGridLoader.h rename : src/game/ObjectMgr.cpp => src/server/game/ObjectMgr.cpp rename : src/game/ObjectMgr.h => src/server/game/ObjectMgr.h rename : src/game/ObjectPosSelector.cpp => src/server/game/ObjectPosSelector.cpp rename : src/game/ObjectPosSelector.h => src/server/game/ObjectPosSelector.h rename : src/game/Opcodes.cpp => src/server/game/Opcodes.cpp rename : src/game/Opcodes.h => src/server/game/Opcodes.h rename : src/game/OutdoorPvP.cpp => src/server/game/OutdoorPvP.cpp rename : src/game/OutdoorPvP.h => src/server/game/OutdoorPvP.h rename : src/game/OutdoorPvPEP.cpp => src/server/game/OutdoorPvPEP.cpp rename : src/game/OutdoorPvPEP.h => src/server/game/OutdoorPvPEP.h rename : src/game/OutdoorPvPHP.cpp => src/server/game/OutdoorPvPHP.cpp rename : src/game/OutdoorPvPHP.h => src/server/game/OutdoorPvPHP.h rename : src/game/OutdoorPvPImpl.h => src/server/game/OutdoorPvPImpl.h rename : src/game/OutdoorPvPMgr.cpp => src/server/game/OutdoorPvPMgr.cpp rename : src/game/OutdoorPvPMgr.h => src/server/game/OutdoorPvPMgr.h rename : src/game/OutdoorPvPNA.cpp => src/server/game/OutdoorPvPNA.cpp rename : src/game/OutdoorPvPNA.h => src/server/game/OutdoorPvPNA.h rename : src/game/OutdoorPvPSI.cpp => src/server/game/OutdoorPvPSI.cpp rename : src/game/OutdoorPvPSI.h => src/server/game/OutdoorPvPSI.h rename : src/game/OutdoorPvPTF.cpp => src/server/game/OutdoorPvPTF.cpp rename : src/game/OutdoorPvPTF.h => src/server/game/OutdoorPvPTF.h rename : src/game/OutdoorPvPZM.cpp => src/server/game/OutdoorPvPZM.cpp rename : src/game/OutdoorPvPZM.h => src/server/game/OutdoorPvPZM.h rename : src/game/PassiveAI.cpp => src/server/game/PassiveAI.cpp rename : src/game/PassiveAI.h => src/server/game/PassiveAI.h rename : src/game/Path.h => src/server/game/Path.h rename : src/game/Pet.cpp => src/server/game/Pet.cpp rename : src/game/Pet.h => src/server/game/Pet.h rename : src/game/PetAI.cpp => src/server/game/PetAI.cpp rename : src/game/PetAI.h => src/server/game/PetAI.h rename : src/game/PetHandler.cpp => src/server/game/PetHandler.cpp rename : src/game/PetitionsHandler.cpp => src/server/game/PetitionsHandler.cpp rename : src/game/Player.cpp => src/server/game/Player.cpp rename : src/game/Player.h => src/server/game/Player.h rename : src/game/PlayerDump.cpp => src/server/game/PlayerDump.cpp rename : src/game/PlayerDump.h => src/server/game/PlayerDump.h rename : src/game/PointMovementGenerator.cpp => src/server/game/PointMovementGenerator.cpp rename : src/game/PointMovementGenerator.h => src/server/game/PointMovementGenerator.h rename : src/game/PoolHandler.cpp => src/server/game/PoolHandler.cpp rename : src/game/PoolHandler.h => src/server/game/PoolHandler.h rename : src/game/QueryHandler.cpp => src/server/game/QueryHandler.cpp rename : src/game/QuestDef.cpp => src/server/game/QuestDef.cpp rename : src/game/QuestDef.h => src/server/game/QuestDef.h rename : src/game/QuestHandler.cpp => src/server/game/QuestHandler.cpp rename : src/game/RandomMovementGenerator.cpp => src/server/game/RandomMovementGenerator.cpp rename : src/game/RandomMovementGenerator.h => src/server/game/RandomMovementGenerator.h rename : src/game/ReactorAI.cpp => src/server/game/ReactorAI.cpp rename : src/game/ReactorAI.h => src/server/game/ReactorAI.h rename : src/game/ReputationMgr.cpp => src/server/game/ReputationMgr.cpp rename : src/game/ReputationMgr.h => src/server/game/ReputationMgr.h rename : src/game/ScriptLoader.cpp => src/server/game/ScriptLoader.cpp rename : src/game/ScriptLoader.h => src/server/game/ScriptLoader.h rename : src/game/ScriptMgr.cpp => src/server/game/ScriptMgr.cpp rename : src/game/ScriptMgr.h => src/server/game/ScriptMgr.h rename : src/game/ScriptSystem.cpp => src/server/game/ScriptSystem.cpp rename : src/game/ScriptSystem.h => src/server/game/ScriptSystem.h rename : src/game/ScriptedCreature.cpp => src/server/game/ScriptedCreature.cpp rename : src/game/ScriptedCreature.h => src/server/game/ScriptedCreature.h rename : src/game/ScriptedEscortAI.cpp => src/server/game/ScriptedEscortAI.cpp rename : src/game/ScriptedEscortAI.h => src/server/game/ScriptedEscortAI.h rename : src/game/ScriptedFollowerAI.cpp => src/server/game/ScriptedFollowerAI.cpp rename : src/game/ScriptedFollowerAI.h => src/server/game/ScriptedFollowerAI.h rename : src/game/ScriptedGossip.h => src/server/game/ScriptedGossip.h rename : src/game/ScriptedGuardAI.cpp => src/server/game/ScriptedGuardAI.cpp rename : src/game/ScriptedGuardAI.h => src/server/game/ScriptedGuardAI.h rename : src/game/ScriptedInstance.h => src/server/game/ScriptedInstance.h rename : src/game/ScriptedPch.cpp => src/server/game/ScriptedPch.cpp rename : src/game/ScriptedPch.h => src/server/game/ScriptedPch.h rename : src/game/ScriptedSimpleAI.cpp => src/server/game/ScriptedSimpleAI.cpp rename : src/game/ScriptedSimpleAI.h => src/server/game/ScriptedSimpleAI.h rename : src/game/ScriptedSmartAI.cpp => src/server/game/ScriptedSmartAI.cpp rename : src/game/ScriptedSmartAI.h => src/server/game/ScriptedSmartAI.h rename : src/game/SharedDefines.h => src/server/game/SharedDefines.h rename : src/game/SkillDiscovery.cpp => src/server/game/SkillDiscovery.cpp rename : src/game/SkillDiscovery.h => src/server/game/SkillDiscovery.h rename : src/game/SkillExtraItems.cpp => src/server/game/SkillExtraItems.cpp rename : src/game/SkillExtraItems.h => src/server/game/SkillExtraItems.h rename : src/game/SkillHandler.cpp => src/server/game/SkillHandler.cpp rename : src/game/SocialMgr.cpp => src/server/game/SocialMgr.cpp rename : src/game/SocialMgr.h => src/server/game/SocialMgr.h rename : src/game/Spell.cpp => src/server/game/Spell.cpp rename : src/game/Spell.h => src/server/game/Spell.h rename : src/game/SpellAuraDefines.h => src/server/game/SpellAuraDefines.h rename : src/game/SpellAuraEffects.cpp => src/server/game/SpellAuraEffects.cpp rename : src/game/SpellAuraEffects.h => src/server/game/SpellAuraEffects.h rename : src/game/SpellAuras.cpp => src/server/game/SpellAuras.cpp rename : src/game/SpellAuras.h => src/server/game/SpellAuras.h rename : src/game/SpellEffects.cpp => src/server/game/SpellEffects.cpp rename : src/game/SpellHandler.cpp => src/server/game/SpellHandler.cpp rename : src/game/SpellMgr.cpp => src/server/game/SpellMgr.cpp rename : src/game/SpellMgr.h => src/server/game/SpellMgr.h rename : src/game/StatSystem.cpp => src/server/game/StatSystem.cpp rename : src/game/TargetedMovementGenerator.cpp => src/server/game/TargetedMovementGenerator.cpp rename : src/game/TargetedMovementGenerator.h => src/server/game/TargetedMovementGenerator.h rename : src/game/TaxiHandler.cpp => src/server/game/TaxiHandler.cpp rename : src/game/TemporarySummon.cpp => src/server/game/TemporarySummon.cpp rename : src/game/TemporarySummon.h => src/server/game/TemporarySummon.h rename : src/game/ThreatManager.cpp => src/server/game/ThreatManager.cpp rename : src/game/ThreatManager.h => src/server/game/ThreatManager.h rename : src/game/TicketHandler.cpp => src/server/game/TicketHandler.cpp rename : src/game/TimeMgr.cpp => src/server/game/TimeMgr.cpp rename : src/game/TimeMgr.h => src/server/game/TimeMgr.h rename : src/game/Tools.cpp => src/server/game/Tools.cpp rename : src/game/Tools.h => src/server/game/Tools.h rename : src/game/Totem.cpp => src/server/game/Totem.cpp rename : src/game/Totem.h => src/server/game/Totem.h rename : src/game/TotemAI.cpp => src/server/game/TotemAI.cpp rename : src/game/TotemAI.h => src/server/game/TotemAI.h rename : src/game/TradeHandler.cpp => src/server/game/TradeHandler.cpp rename : src/game/Transports.cpp => src/server/game/Transports.cpp rename : src/game/Transports.h => src/server/game/Transports.h rename : src/game/Traveller.h => src/server/game/Traveller.h rename : src/game/Unit.cpp => src/server/game/Unit.cpp rename : src/game/Unit.h => src/server/game/Unit.h rename : src/game/UnitAI.cpp => src/server/game/UnitAI.cpp rename : src/game/UnitAI.h => src/server/game/UnitAI.h rename : src/game/UnitEvents.h => src/server/game/UnitEvents.h rename : src/game/UpdateData.cpp => src/server/game/UpdateData.cpp rename : src/game/UpdateData.h => src/server/game/UpdateData.h rename : src/game/UpdateFields.h => src/server/game/UpdateFields.h rename : src/game/UpdateMask.h => src/server/game/UpdateMask.h rename : src/game/Vehicle.cpp => src/server/game/Vehicle.cpp rename : src/game/Vehicle.h => src/server/game/Vehicle.h rename : src/game/VoiceChatHandler.cpp => src/server/game/VoiceChatHandler.cpp rename : src/game/WaypointManager.cpp => src/server/game/WaypointManager.cpp rename : src/game/WaypointManager.h => src/server/game/WaypointManager.h rename : src/game/WaypointMovementGenerator.cpp => src/server/game/WaypointMovementGenerator.cpp rename : src/game/WaypointMovementGenerator.h => src/server/game/WaypointMovementGenerator.h rename : src/game/Weather.cpp => src/server/game/Weather.cpp rename : src/game/Weather.h => src/server/game/Weather.h rename : src/game/World.cpp => src/server/game/World.cpp rename : src/game/World.h => src/server/game/World.h rename : src/game/WorldLog.cpp => src/server/game/WorldLog.cpp rename : src/game/WorldLog.h => src/server/game/WorldLog.h rename : src/game/WorldSession.cpp => src/server/game/WorldSession.cpp rename : src/game/WorldSession.h => src/server/game/WorldSession.h rename : src/game/WorldSocket.cpp => src/server/game/WorldSocket.cpp rename : src/game/WorldSocket.h => src/server/game/WorldSocket.h rename : src/game/WorldSocketMgr.cpp => src/server/game/WorldSocketMgr.cpp rename : src/game/WorldSocketMgr.h => src/server/game/WorldSocketMgr.h rename : src/game/ZoneScript.h => src/server/game/ZoneScript.h rename : src/game/pchdef.cpp => src/server/game/pchdef.cpp rename : src/game/pchdef.h => src/server/game/pchdef.h rename : src/game/pchlinux.cpp => src/server/game/pchlinux.cpp rename : src/game/pchlinux.h => src/server/game/pchlinux.h rename : src/scripts/CMakeLists.txt => src/server/scripts/CMakeLists.txt rename : src/scripts/custom/custom_example.cpp => src/server/scripts/custom/custom_example.cpp rename : src/scripts/custom/custom_gossip_codebox.cpp => src/server/scripts/custom/custom_gossip_codebox.cpp rename : src/scripts/custom/npc_acherus_taxi.cpp => src/server/scripts/custom/npc_acherus_taxi.cpp rename : src/scripts/custom/npc_wyrmresttempel_taxi.cpp => src/server/scripts/custom/npc_wyrmresttempel_taxi.cpp rename : src/scripts/custom/on_events.cpp => src/server/scripts/custom/on_events.cpp rename : src/scripts/custom/test.cpp => src/server/scripts/custom/test.cpp rename : src/scripts/eastern_kingdoms/alterac_mountains.cpp => src/server/scripts/eastern_kingdoms/alterac_mountains.cpp rename : src/scripts/eastern_kingdoms/alterac_valley/alterac_valley.cpp => src/server/scripts/eastern_kingdoms/alterac_valley/alterac_valley.cpp rename : src/scripts/eastern_kingdoms/alterac_valley/boss_balinda.cpp => src/server/scripts/eastern_kingdoms/alterac_valley/boss_balinda.cpp rename : src/scripts/eastern_kingdoms/alterac_valley/boss_drekthar.cpp => src/server/scripts/eastern_kingdoms/alterac_valley/boss_drekthar.cpp rename : src/scripts/eastern_kingdoms/alterac_valley/boss_galvangar.cpp => src/server/scripts/eastern_kingdoms/alterac_valley/boss_galvangar.cpp rename : src/scripts/eastern_kingdoms/alterac_valley/boss_vanndar.cpp => src/server/scripts/eastern_kingdoms/alterac_valley/boss_vanndar.cpp rename : src/scripts/eastern_kingdoms/arathi_highlands.cpp => src/server/scripts/eastern_kingdoms/arathi_highlands.cpp rename : src/scripts/eastern_kingdoms/blackrock_depths/blackrock_depths.cpp => src/server/scripts/eastern_kingdoms/blackrock_depths/blackrock_depths.cpp rename : src/scripts/eastern_kingdoms/blackrock_depths/blackrock_depths.h => src/server/scripts/eastern_kingdoms/blackrock_depths/blackrock_depths.h rename : src/scripts/eastern_kingdoms/blackrock_depths/boss_ambassador_flamelash.cpp => src/server/scripts/eastern_kingdoms/blackrock_depths/boss_ambassador_flamelash.cpp rename : src/scripts/eastern_kingdoms/blackrock_depths/boss_anubshiah.cpp => src/server/scripts/eastern_kingdoms/blackrock_depths/boss_anubshiah.cpp rename : src/scripts/eastern_kingdoms/blackrock_depths/boss_emperor_dagran_thaurissan.cpp => src/server/scripts/eastern_kingdoms/blackrock_depths/boss_emperor_dagran_thaurissan.cpp rename : src/scripts/eastern_kingdoms/blackrock_depths/boss_general_angerforge.cpp => src/server/scripts/eastern_kingdoms/blackrock_depths/boss_general_angerforge.cpp rename : src/scripts/eastern_kingdoms/blackrock_depths/boss_gorosh_the_dervish.cpp => src/server/scripts/eastern_kingdoms/blackrock_depths/boss_gorosh_the_dervish.cpp rename : src/scripts/eastern_kingdoms/blackrock_depths/boss_grizzle.cpp => src/server/scripts/eastern_kingdoms/blackrock_depths/boss_grizzle.cpp rename : src/scripts/eastern_kingdoms/blackrock_depths/boss_high_interrogator_gerstahn.cpp => src/server/scripts/eastern_kingdoms/blackrock_depths/boss_high_interrogator_gerstahn.cpp rename : src/scripts/eastern_kingdoms/blackrock_depths/boss_magmus.cpp => src/server/scripts/eastern_kingdoms/blackrock_depths/boss_magmus.cpp rename : src/scripts/eastern_kingdoms/blackrock_depths/boss_moira_bronzebeard.cpp => src/server/scripts/eastern_kingdoms/blackrock_depths/boss_moira_bronzebeard.cpp rename : src/scripts/eastern_kingdoms/blackrock_depths/boss_tomb_of_seven.cpp => src/server/scripts/eastern_kingdoms/blackrock_depths/boss_tomb_of_seven.cpp rename : src/scripts/eastern_kingdoms/blackrock_depths/instance_blackrock_depths.cpp => src/server/scripts/eastern_kingdoms/blackrock_depths/instance_blackrock_depths.cpp rename : src/scripts/eastern_kingdoms/blackrock_spire/blackrock_spire.cpp => src/server/scripts/eastern_kingdoms/blackrock_spire/blackrock_spire.cpp rename : src/scripts/eastern_kingdoms/blackrock_spire/blackrock_spire.h => src/server/scripts/eastern_kingdoms/blackrock_spire/blackrock_spire.h rename : src/scripts/eastern_kingdoms/blackrock_spire/boss_drakkisath.cpp => src/server/scripts/eastern_kingdoms/blackrock_spire/boss_drakkisath.cpp rename : src/scripts/eastern_kingdoms/blackrock_spire/boss_gyth.cpp => src/server/scripts/eastern_kingdoms/blackrock_spire/boss_gyth.cpp rename : src/scripts/eastern_kingdoms/blackrock_spire/boss_halycon.cpp => src/server/scripts/eastern_kingdoms/blackrock_spire/boss_halycon.cpp rename : src/scripts/eastern_kingdoms/blackrock_spire/boss_highlord_omokk.cpp => src/server/scripts/eastern_kingdoms/blackrock_spire/boss_highlord_omokk.cpp rename : src/scripts/eastern_kingdoms/blackrock_spire/boss_mother_smolderweb.cpp => src/server/scripts/eastern_kingdoms/blackrock_spire/boss_mother_smolderweb.cpp rename : src/scripts/eastern_kingdoms/blackrock_spire/boss_overlord_wyrmthalak.cpp => src/server/scripts/eastern_kingdoms/blackrock_spire/boss_overlord_wyrmthalak.cpp rename : src/scripts/eastern_kingdoms/blackrock_spire/boss_pyroguard_emberseer.cpp => src/server/scripts/eastern_kingdoms/blackrock_spire/boss_pyroguard_emberseer.cpp rename : src/scripts/eastern_kingdoms/blackrock_spire/boss_quartermaster_zigris.cpp => src/server/scripts/eastern_kingdoms/blackrock_spire/boss_quartermaster_zigris.cpp rename : src/scripts/eastern_kingdoms/blackrock_spire/boss_rend_blackhand.cpp => src/server/scripts/eastern_kingdoms/blackrock_spire/boss_rend_blackhand.cpp rename : src/scripts/eastern_kingdoms/blackrock_spire/boss_shadow_hunter_voshgajin.cpp => src/server/scripts/eastern_kingdoms/blackrock_spire/boss_shadow_hunter_voshgajin.cpp rename : src/scripts/eastern_kingdoms/blackrock_spire/boss_the_beast.cpp => src/server/scripts/eastern_kingdoms/blackrock_spire/boss_the_beast.cpp rename : src/scripts/eastern_kingdoms/blackrock_spire/boss_warmaster_voone.cpp => src/server/scripts/eastern_kingdoms/blackrock_spire/boss_warmaster_voone.cpp rename : src/scripts/eastern_kingdoms/blackrock_spire/instance_blackrock_spire.cpp => src/server/scripts/eastern_kingdoms/blackrock_spire/instance_blackrock_spire.cpp rename : src/scripts/eastern_kingdoms/blackwing_lair/boss_broodlord_lashlayer.cpp => src/server/scripts/eastern_kingdoms/blackwing_lair/boss_broodlord_lashlayer.cpp rename : src/scripts/eastern_kingdoms/blackwing_lair/boss_chromaggus.cpp => src/server/scripts/eastern_kingdoms/blackwing_lair/boss_chromaggus.cpp rename : src/scripts/eastern_kingdoms/blackwing_lair/boss_ebonroc.cpp => src/server/scripts/eastern_kingdoms/blackwing_lair/boss_ebonroc.cpp rename : src/scripts/eastern_kingdoms/blackwing_lair/boss_firemaw.cpp => src/server/scripts/eastern_kingdoms/blackwing_lair/boss_firemaw.cpp rename : src/scripts/eastern_kingdoms/blackwing_lair/boss_flamegor.cpp => src/server/scripts/eastern_kingdoms/blackwing_lair/boss_flamegor.cpp rename : src/scripts/eastern_kingdoms/blackwing_lair/boss_nefarian.cpp => src/server/scripts/eastern_kingdoms/blackwing_lair/boss_nefarian.cpp rename : src/scripts/eastern_kingdoms/blackwing_lair/boss_razorgore.cpp => src/server/scripts/eastern_kingdoms/blackwing_lair/boss_razorgore.cpp rename : src/scripts/eastern_kingdoms/blackwing_lair/boss_vaelastrasz.cpp => src/server/scripts/eastern_kingdoms/blackwing_lair/boss_vaelastrasz.cpp rename : src/scripts/eastern_kingdoms/blackwing_lair/boss_victor_nefarius.cpp => src/server/scripts/eastern_kingdoms/blackwing_lair/boss_victor_nefarius.cpp rename : src/scripts/eastern_kingdoms/blackwing_lair/instance_blackwing_lair.cpp => src/server/scripts/eastern_kingdoms/blackwing_lair/instance_blackwing_lair.cpp rename : src/scripts/eastern_kingdoms/blasted_lands.cpp => src/server/scripts/eastern_kingdoms/blasted_lands.cpp rename : src/scripts/eastern_kingdoms/boss_kruul.cpp => src/server/scripts/eastern_kingdoms/boss_kruul.cpp rename : src/scripts/eastern_kingdoms/burning_steppes.cpp => src/server/scripts/eastern_kingdoms/burning_steppes.cpp rename : src/scripts/eastern_kingdoms/deadmines/boss_mr_smite.cpp => src/server/scripts/eastern_kingdoms/deadmines/boss_mr_smite.cpp rename : src/scripts/eastern_kingdoms/deadmines/deadmines.cpp => src/server/scripts/eastern_kingdoms/deadmines/deadmines.cpp rename : src/scripts/eastern_kingdoms/deadmines/deadmines.h => src/server/scripts/eastern_kingdoms/deadmines/deadmines.h rename : src/scripts/eastern_kingdoms/deadmines/instance_deadmines.cpp => src/server/scripts/eastern_kingdoms/deadmines/instance_deadmines.cpp rename : src/scripts/eastern_kingdoms/dun_morogh.cpp => src/server/scripts/eastern_kingdoms/dun_morogh.cpp rename : src/scripts/eastern_kingdoms/duskwood.cpp => src/server/scripts/eastern_kingdoms/duskwood.cpp rename : src/scripts/eastern_kingdoms/eastern_plaguelands.cpp => src/server/scripts/eastern_kingdoms/eastern_plaguelands.cpp rename : src/scripts/eastern_kingdoms/elwynn_forest.cpp => src/server/scripts/eastern_kingdoms/elwynn_forest.cpp rename : src/scripts/eastern_kingdoms/eversong_woods.cpp => src/server/scripts/eastern_kingdoms/eversong_woods.cpp rename : src/scripts/eastern_kingdoms/ghostlands.cpp => src/server/scripts/eastern_kingdoms/ghostlands.cpp rename : src/scripts/eastern_kingdoms/gnomeregan/gnomeregan.cpp => src/server/scripts/eastern_kingdoms/gnomeregan/gnomeregan.cpp rename : src/scripts/eastern_kingdoms/gnomeregan/gnomeregan.h => src/server/scripts/eastern_kingdoms/gnomeregan/gnomeregan.h rename : src/scripts/eastern_kingdoms/gnomeregan/instance_gnomeregan.cpp => src/server/scripts/eastern_kingdoms/gnomeregan/instance_gnomeregan.cpp rename : src/scripts/eastern_kingdoms/hinterlands.cpp => src/server/scripts/eastern_kingdoms/hinterlands.cpp rename : src/scripts/eastern_kingdoms/ironforge.cpp => src/server/scripts/eastern_kingdoms/ironforge.cpp rename : src/scripts/eastern_kingdoms/isle_of_queldanas.cpp => src/server/scripts/eastern_kingdoms/isle_of_queldanas.cpp rename : src/scripts/eastern_kingdoms/karazhan/boss_curator.cpp => src/server/scripts/eastern_kingdoms/karazhan/boss_curator.cpp rename : src/scripts/eastern_kingdoms/karazhan/boss_maiden_of_virtue.cpp => src/server/scripts/eastern_kingdoms/karazhan/boss_maiden_of_virtue.cpp rename : src/scripts/eastern_kingdoms/karazhan/boss_midnight.cpp => src/server/scripts/eastern_kingdoms/karazhan/boss_midnight.cpp rename : src/scripts/eastern_kingdoms/karazhan/boss_moroes.cpp => src/server/scripts/eastern_kingdoms/karazhan/boss_moroes.cpp rename : src/scripts/eastern_kingdoms/karazhan/boss_netherspite.cpp => src/server/scripts/eastern_kingdoms/karazhan/boss_netherspite.cpp rename : src/scripts/eastern_kingdoms/karazhan/boss_nightbane.cpp => src/server/scripts/eastern_kingdoms/karazhan/boss_nightbane.cpp rename : src/scripts/eastern_kingdoms/karazhan/boss_prince_malchezaar.cpp => src/server/scripts/eastern_kingdoms/karazhan/boss_prince_malchezaar.cpp rename : src/scripts/eastern_kingdoms/karazhan/boss_shade_of_aran.cpp => src/server/scripts/eastern_kingdoms/karazhan/boss_shade_of_aran.cpp rename : src/scripts/eastern_kingdoms/karazhan/boss_terestian_illhoof.cpp => src/server/scripts/eastern_kingdoms/karazhan/boss_terestian_illhoof.cpp rename : src/scripts/eastern_kingdoms/karazhan/bosses_opera.cpp => src/server/scripts/eastern_kingdoms/karazhan/bosses_opera.cpp rename : src/scripts/eastern_kingdoms/karazhan/instance_karazhan.cpp => src/server/scripts/eastern_kingdoms/karazhan/instance_karazhan.cpp rename : src/scripts/eastern_kingdoms/karazhan/karazhan.cpp => src/server/scripts/eastern_kingdoms/karazhan/karazhan.cpp rename : src/scripts/eastern_kingdoms/karazhan/karazhan.h => src/server/scripts/eastern_kingdoms/karazhan/karazhan.h rename : src/scripts/eastern_kingdoms/loch_modan.cpp => src/server/scripts/eastern_kingdoms/loch_modan.cpp rename : src/scripts/eastern_kingdoms/magisters_terrace/boss_felblood_kaelthas.cpp => src/server/scripts/eastern_kingdoms/magisters_terrace/boss_felblood_kaelthas.cpp rename : src/scripts/eastern_kingdoms/magisters_terrace/boss_priestess_delrissa.cpp => src/server/scripts/eastern_kingdoms/magisters_terrace/boss_priestess_delrissa.cpp rename : src/scripts/eastern_kingdoms/magisters_terrace/boss_selin_fireheart.cpp => src/server/scripts/eastern_kingdoms/magisters_terrace/boss_selin_fireheart.cpp rename : src/scripts/eastern_kingdoms/magisters_terrace/boss_vexallus.cpp => src/server/scripts/eastern_kingdoms/magisters_terrace/boss_vexallus.cpp rename : src/scripts/eastern_kingdoms/magisters_terrace/instance_magisters_terrace.cpp => src/server/scripts/eastern_kingdoms/magisters_terrace/instance_magisters_terrace.cpp rename : src/scripts/eastern_kingdoms/magisters_terrace/magisters_terrace.cpp => src/server/scripts/eastern_kingdoms/magisters_terrace/magisters_terrace.cpp rename : src/scripts/eastern_kingdoms/magisters_terrace/magisters_terrace.h => src/server/scripts/eastern_kingdoms/magisters_terrace/magisters_terrace.h rename : src/scripts/eastern_kingdoms/molten_core/boss_baron_geddon.cpp => src/server/scripts/eastern_kingdoms/molten_core/boss_baron_geddon.cpp rename : src/scripts/eastern_kingdoms/molten_core/boss_garr.cpp => src/server/scripts/eastern_kingdoms/molten_core/boss_garr.cpp rename : src/scripts/eastern_kingdoms/molten_core/boss_gehennas.cpp => src/server/scripts/eastern_kingdoms/molten_core/boss_gehennas.cpp rename : src/scripts/eastern_kingdoms/molten_core/boss_golemagg.cpp => src/server/scripts/eastern_kingdoms/molten_core/boss_golemagg.cpp rename : src/scripts/eastern_kingdoms/molten_core/boss_lucifron.cpp => src/server/scripts/eastern_kingdoms/molten_core/boss_lucifron.cpp rename : src/scripts/eastern_kingdoms/molten_core/boss_magmadar.cpp => src/server/scripts/eastern_kingdoms/molten_core/boss_magmadar.cpp rename : src/scripts/eastern_kingdoms/molten_core/boss_majordomo_executus.cpp => src/server/scripts/eastern_kingdoms/molten_core/boss_majordomo_executus.cpp rename : src/scripts/eastern_kingdoms/molten_core/boss_ragnaros.cpp => src/server/scripts/eastern_kingdoms/molten_core/boss_ragnaros.cpp rename : src/scripts/eastern_kingdoms/molten_core/boss_shazzrah.cpp => src/server/scripts/eastern_kingdoms/molten_core/boss_shazzrah.cpp rename : src/scripts/eastern_kingdoms/molten_core/boss_sulfuron_harbinger.cpp => src/server/scripts/eastern_kingdoms/molten_core/boss_sulfuron_harbinger.cpp rename : src/scripts/eastern_kingdoms/molten_core/instance_molten_core.cpp => src/server/scripts/eastern_kingdoms/molten_core/instance_molten_core.cpp rename : src/scripts/eastern_kingdoms/molten_core/molten_core.cpp => src/server/scripts/eastern_kingdoms/molten_core/molten_core.cpp rename : src/scripts/eastern_kingdoms/molten_core/molten_core.h => src/server/scripts/eastern_kingdoms/molten_core/molten_core.h rename : src/scripts/eastern_kingdoms/redridge_mountains.cpp => src/server/scripts/eastern_kingdoms/redridge_mountains.cpp rename : src/scripts/eastern_kingdoms/scarlet_enclave/chapter1.cpp => src/server/scripts/eastern_kingdoms/scarlet_enclave/chapter1.cpp rename : src/scripts/eastern_kingdoms/scarlet_enclave/chapter2.cpp => src/server/scripts/eastern_kingdoms/scarlet_enclave/chapter2.cpp rename : src/scripts/eastern_kingdoms/scarlet_enclave/chapter5.cpp => src/server/scripts/eastern_kingdoms/scarlet_enclave/chapter5.cpp rename : src/scripts/eastern_kingdoms/scarlet_enclave/the_scarlet_enclave.cpp => src/server/scripts/eastern_kingdoms/scarlet_enclave/the_scarlet_enclave.cpp rename : src/scripts/eastern_kingdoms/scarlet_monastery/boss_arcanist_doan.cpp => src/server/scripts/eastern_kingdoms/scarlet_monastery/boss_arcanist_doan.cpp rename : src/scripts/eastern_kingdoms/scarlet_monastery/boss_azshir_the_sleepless.cpp => src/server/scripts/eastern_kingdoms/scarlet_monastery/boss_azshir_the_sleepless.cpp rename : src/scripts/eastern_kingdoms/scarlet_monastery/boss_bloodmage_thalnos.cpp => src/server/scripts/eastern_kingdoms/scarlet_monastery/boss_bloodmage_thalnos.cpp rename : src/scripts/eastern_kingdoms/scarlet_monastery/boss_headless_horseman.cpp => src/server/scripts/eastern_kingdoms/scarlet_monastery/boss_headless_horseman.cpp rename : src/scripts/eastern_kingdoms/scarlet_monastery/boss_herod.cpp => src/server/scripts/eastern_kingdoms/scarlet_monastery/boss_herod.cpp rename : src/scripts/eastern_kingdoms/scarlet_monastery/boss_high_inquisitor_fairbanks.cpp => src/server/scripts/eastern_kingdoms/scarlet_monastery/boss_high_inquisitor_fairbanks.cpp rename : src/scripts/eastern_kingdoms/scarlet_monastery/boss_houndmaster_loksey.cpp => src/server/scripts/eastern_kingdoms/scarlet_monastery/boss_houndmaster_loksey.cpp rename : src/scripts/eastern_kingdoms/scarlet_monastery/boss_interrogator_vishas.cpp => src/server/scripts/eastern_kingdoms/scarlet_monastery/boss_interrogator_vishas.cpp rename : src/scripts/eastern_kingdoms/scarlet_monastery/boss_mograine_and_whitemane.cpp => src/server/scripts/eastern_kingdoms/scarlet_monastery/boss_mograine_and_whitemane.cpp rename : src/scripts/eastern_kingdoms/scarlet_monastery/boss_scorn.cpp => src/server/scripts/eastern_kingdoms/scarlet_monastery/boss_scorn.cpp rename : src/scripts/eastern_kingdoms/scarlet_monastery/instance_scarlet_monastery.cpp => src/server/scripts/eastern_kingdoms/scarlet_monastery/instance_scarlet_monastery.cpp rename : src/scripts/eastern_kingdoms/scarlet_monastery/scarlet_monastery.h => src/server/scripts/eastern_kingdoms/scarlet_monastery/scarlet_monastery.h rename : src/scripts/eastern_kingdoms/scholomance/boss_darkmaster_gandling.cpp => src/server/scripts/eastern_kingdoms/scholomance/boss_darkmaster_gandling.cpp rename : src/scripts/eastern_kingdoms/scholomance/boss_death_knight_darkreaver.cpp => src/server/scripts/eastern_kingdoms/scholomance/boss_death_knight_darkreaver.cpp rename : src/scripts/eastern_kingdoms/scholomance/boss_doctor_theolen_krastinov.cpp => src/server/scripts/eastern_kingdoms/scholomance/boss_doctor_theolen_krastinov.cpp rename : src/scripts/eastern_kingdoms/scholomance/boss_illucia_barov.cpp => src/server/scripts/eastern_kingdoms/scholomance/boss_illucia_barov.cpp rename : src/scripts/eastern_kingdoms/scholomance/boss_instructor_malicia.cpp => src/server/scripts/eastern_kingdoms/scholomance/boss_instructor_malicia.cpp rename : src/scripts/eastern_kingdoms/scholomance/boss_jandice_barov.cpp => src/server/scripts/eastern_kingdoms/scholomance/boss_jandice_barov.cpp rename : src/scripts/eastern_kingdoms/scholomance/boss_kormok.cpp => src/server/scripts/eastern_kingdoms/scholomance/boss_kormok.cpp rename : src/scripts/eastern_kingdoms/scholomance/boss_lord_alexei_barov.cpp => src/server/scripts/eastern_kingdoms/scholomance/boss_lord_alexei_barov.cpp rename : src/scripts/eastern_kingdoms/scholomance/boss_lorekeeper_polkelt.cpp => src/server/scripts/eastern_kingdoms/scholomance/boss_lorekeeper_polkelt.cpp rename : src/scripts/eastern_kingdoms/scholomance/boss_ras_frostwhisper.cpp => src/server/scripts/eastern_kingdoms/scholomance/boss_ras_frostwhisper.cpp rename : src/scripts/eastern_kingdoms/scholomance/boss_the_ravenian.cpp => src/server/scripts/eastern_kingdoms/scholomance/boss_the_ravenian.cpp rename : src/scripts/eastern_kingdoms/scholomance/boss_vectus.cpp => src/server/scripts/eastern_kingdoms/scholomance/boss_vectus.cpp rename : src/scripts/eastern_kingdoms/scholomance/instance_scholomance.cpp => src/server/scripts/eastern_kingdoms/scholomance/instance_scholomance.cpp rename : src/scripts/eastern_kingdoms/scholomance/scholomance.h => src/server/scripts/eastern_kingdoms/scholomance/scholomance.h rename : src/scripts/eastern_kingdoms/searing_gorge.cpp => src/server/scripts/eastern_kingdoms/searing_gorge.cpp rename : src/scripts/eastern_kingdoms/shadowfang_keep/instance_shadowfang_keep.cpp => src/server/scripts/eastern_kingdoms/shadowfang_keep/instance_shadowfang_keep.cpp rename : src/scripts/eastern_kingdoms/shadowfang_keep/shadowfang_keep.cpp => src/server/scripts/eastern_kingdoms/shadowfang_keep/shadowfang_keep.cpp rename : src/scripts/eastern_kingdoms/shadowfang_keep/shadowfang_keep.h => src/server/scripts/eastern_kingdoms/shadowfang_keep/shadowfang_keep.h rename : src/scripts/eastern_kingdoms/silvermoon_city.cpp => src/server/scripts/eastern_kingdoms/silvermoon_city.cpp rename : src/scripts/eastern_kingdoms/silverpine_forest.cpp => src/server/scripts/eastern_kingdoms/silverpine_forest.cpp rename : src/scripts/eastern_kingdoms/stormwind_city.cpp => src/server/scripts/eastern_kingdoms/stormwind_city.cpp rename : src/scripts/eastern_kingdoms/stranglethorn_vale.cpp => src/server/scripts/eastern_kingdoms/stranglethorn_vale.cpp rename : src/scripts/eastern_kingdoms/stratholme/boss_baron_rivendare.cpp => src/server/scripts/eastern_kingdoms/stratholme/boss_baron_rivendare.cpp rename : src/scripts/eastern_kingdoms/stratholme/boss_baroness_anastari.cpp => src/server/scripts/eastern_kingdoms/stratholme/boss_baroness_anastari.cpp rename : src/scripts/eastern_kingdoms/stratholme/boss_cannon_master_willey.cpp => src/server/scripts/eastern_kingdoms/stratholme/boss_cannon_master_willey.cpp rename : src/scripts/eastern_kingdoms/stratholme/boss_dathrohan_balnazzar.cpp => src/server/scripts/eastern_kingdoms/stratholme/boss_dathrohan_balnazzar.cpp rename : src/scripts/eastern_kingdoms/stratholme/boss_magistrate_barthilas.cpp => src/server/scripts/eastern_kingdoms/stratholme/boss_magistrate_barthilas.cpp rename : src/scripts/eastern_kingdoms/stratholme/boss_maleki_the_pallid.cpp => src/server/scripts/eastern_kingdoms/stratholme/boss_maleki_the_pallid.cpp rename : src/scripts/eastern_kingdoms/stratholme/boss_nerubenkan.cpp => src/server/scripts/eastern_kingdoms/stratholme/boss_nerubenkan.cpp rename : src/scripts/eastern_kingdoms/stratholme/boss_order_of_silver_hand.cpp => src/server/scripts/eastern_kingdoms/stratholme/boss_order_of_silver_hand.cpp rename : src/scripts/eastern_kingdoms/stratholme/boss_postmaster_malown.cpp => src/server/scripts/eastern_kingdoms/stratholme/boss_postmaster_malown.cpp rename : src/scripts/eastern_kingdoms/stratholme/boss_ramstein_the_gorger.cpp => src/server/scripts/eastern_kingdoms/stratholme/boss_ramstein_the_gorger.cpp rename : src/scripts/eastern_kingdoms/stratholme/boss_timmy_the_cruel.cpp => src/server/scripts/eastern_kingdoms/stratholme/boss_timmy_the_cruel.cpp rename : src/scripts/eastern_kingdoms/stratholme/instance_stratholme.cpp => src/server/scripts/eastern_kingdoms/stratholme/instance_stratholme.cpp rename : src/scripts/eastern_kingdoms/stratholme/stratholme.cpp => src/server/scripts/eastern_kingdoms/stratholme/stratholme.cpp rename : src/scripts/eastern_kingdoms/stratholme/stratholme.h => src/server/scripts/eastern_kingdoms/stratholme/stratholme.h rename : src/scripts/eastern_kingdoms/sunken_temple/instance_sunken_temple.cpp => src/server/scripts/eastern_kingdoms/sunken_temple/instance_sunken_temple.cpp rename : src/scripts/eastern_kingdoms/sunken_temple/sunken_temple.cpp => src/server/scripts/eastern_kingdoms/sunken_temple/sunken_temple.cpp rename : src/scripts/eastern_kingdoms/sunken_temple/sunken_temple.h => src/server/scripts/eastern_kingdoms/sunken_temple/sunken_temple.h rename : src/scripts/eastern_kingdoms/sunwell_plateau/boss_brutallus.cpp => src/server/scripts/eastern_kingdoms/sunwell_plateau/boss_brutallus.cpp rename : src/scripts/eastern_kingdoms/sunwell_plateau/boss_eredar_twins.cpp => src/server/scripts/eastern_kingdoms/sunwell_plateau/boss_eredar_twins.cpp rename : src/scripts/eastern_kingdoms/sunwell_plateau/boss_felmyst.cpp => src/server/scripts/eastern_kingdoms/sunwell_plateau/boss_felmyst.cpp rename : src/scripts/eastern_kingdoms/sunwell_plateau/boss_kalecgos.cpp => src/server/scripts/eastern_kingdoms/sunwell_plateau/boss_kalecgos.cpp rename : src/scripts/eastern_kingdoms/sunwell_plateau/boss_kiljaeden.cpp => src/server/scripts/eastern_kingdoms/sunwell_plateau/boss_kiljaeden.cpp rename : src/scripts/eastern_kingdoms/sunwell_plateau/boss_muru.cpp => src/server/scripts/eastern_kingdoms/sunwell_plateau/boss_muru.cpp rename : src/scripts/eastern_kingdoms/sunwell_plateau/instance_sunwell_plateau.cpp => src/server/scripts/eastern_kingdoms/sunwell_plateau/instance_sunwell_plateau.cpp rename : src/scripts/eastern_kingdoms/sunwell_plateau/sunwell_plateau.cpp => src/server/scripts/eastern_kingdoms/sunwell_plateau/sunwell_plateau.cpp rename : src/scripts/eastern_kingdoms/sunwell_plateau/sunwell_plateau.h => src/server/scripts/eastern_kingdoms/sunwell_plateau/sunwell_plateau.h rename : src/scripts/eastern_kingdoms/tirisfal_glades.cpp => src/server/scripts/eastern_kingdoms/tirisfal_glades.cpp rename : src/scripts/eastern_kingdoms/uldaman/boss_archaedas.cpp => src/server/scripts/eastern_kingdoms/uldaman/boss_archaedas.cpp rename : src/scripts/eastern_kingdoms/uldaman/boss_ironaya.cpp => src/server/scripts/eastern_kingdoms/uldaman/boss_ironaya.cpp rename : src/scripts/eastern_kingdoms/uldaman/instance_uldaman.cpp => src/server/scripts/eastern_kingdoms/uldaman/instance_uldaman.cpp rename : src/scripts/eastern_kingdoms/uldaman/uldaman.cpp => src/server/scripts/eastern_kingdoms/uldaman/uldaman.cpp rename : src/scripts/eastern_kingdoms/undercity.cpp => src/server/scripts/eastern_kingdoms/undercity.cpp rename : src/scripts/eastern_kingdoms/western_plaguelands.cpp => src/server/scripts/eastern_kingdoms/western_plaguelands.cpp rename : src/scripts/eastern_kingdoms/westfall.cpp => src/server/scripts/eastern_kingdoms/westfall.cpp rename : src/scripts/eastern_kingdoms/wetlands.cpp => src/server/scripts/eastern_kingdoms/wetlands.cpp rename : src/scripts/eastern_kingdoms/zulaman/boss_akilzon.cpp => src/server/scripts/eastern_kingdoms/zulaman/boss_akilzon.cpp rename : src/scripts/eastern_kingdoms/zulaman/boss_halazzi.cpp => src/server/scripts/eastern_kingdoms/zulaman/boss_halazzi.cpp rename : src/scripts/eastern_kingdoms/zulaman/boss_hexlord.cpp => src/server/scripts/eastern_kingdoms/zulaman/boss_hexlord.cpp rename : src/scripts/eastern_kingdoms/zulaman/boss_janalai.cpp => src/server/scripts/eastern_kingdoms/zulaman/boss_janalai.cpp rename : src/scripts/eastern_kingdoms/zulaman/boss_nalorakk.cpp => src/server/scripts/eastern_kingdoms/zulaman/boss_nalorakk.cpp rename : src/scripts/eastern_kingdoms/zulaman/boss_zuljin.cpp => src/server/scripts/eastern_kingdoms/zulaman/boss_zuljin.cpp rename : src/scripts/eastern_kingdoms/zulaman/instance_zulaman.cpp => src/server/scripts/eastern_kingdoms/zulaman/instance_zulaman.cpp rename : src/scripts/eastern_kingdoms/zulaman/zulaman.cpp => src/server/scripts/eastern_kingdoms/zulaman/zulaman.cpp rename : src/scripts/eastern_kingdoms/zulaman/zulaman.h => src/server/scripts/eastern_kingdoms/zulaman/zulaman.h rename : src/scripts/eastern_kingdoms/zulgurub/boss_arlokk.cpp => src/server/scripts/eastern_kingdoms/zulgurub/boss_arlokk.cpp rename : src/scripts/eastern_kingdoms/zulgurub/boss_gahzranka.cpp => src/server/scripts/eastern_kingdoms/zulgurub/boss_gahzranka.cpp rename : src/scripts/eastern_kingdoms/zulgurub/boss_grilek.cpp => src/server/scripts/eastern_kingdoms/zulgurub/boss_grilek.cpp rename : src/scripts/eastern_kingdoms/zulgurub/boss_hakkar.cpp => src/server/scripts/eastern_kingdoms/zulgurub/boss_hakkar.cpp rename : src/scripts/eastern_kingdoms/zulgurub/boss_hazzarah.cpp => src/server/scripts/eastern_kingdoms/zulgurub/boss_hazzarah.cpp rename : src/scripts/eastern_kingdoms/zulgurub/boss_jeklik.cpp => src/server/scripts/eastern_kingdoms/zulgurub/boss_jeklik.cpp rename : src/scripts/eastern_kingdoms/zulgurub/boss_jindo.cpp => src/server/scripts/eastern_kingdoms/zulgurub/boss_jindo.cpp rename : src/scripts/eastern_kingdoms/zulgurub/boss_mandokir.cpp => src/server/scripts/eastern_kingdoms/zulgurub/boss_mandokir.cpp rename : src/scripts/eastern_kingdoms/zulgurub/boss_marli.cpp => src/server/scripts/eastern_kingdoms/zulgurub/boss_marli.cpp rename : src/scripts/eastern_kingdoms/zulgurub/boss_renataki.cpp => src/server/scripts/eastern_kingdoms/zulgurub/boss_renataki.cpp rename : src/scripts/eastern_kingdoms/zulgurub/boss_thekal.cpp => src/server/scripts/eastern_kingdoms/zulgurub/boss_thekal.cpp rename : src/scripts/eastern_kingdoms/zulgurub/boss_venoxis.cpp => src/server/scripts/eastern_kingdoms/zulgurub/boss_venoxis.cpp rename : src/scripts/eastern_kingdoms/zulgurub/boss_wushoolay.cpp => src/server/scripts/eastern_kingdoms/zulgurub/boss_wushoolay.cpp rename : src/scripts/eastern_kingdoms/zulgurub/instance_zulgurub.cpp => src/server/scripts/eastern_kingdoms/zulgurub/instance_zulgurub.cpp rename : src/scripts/eastern_kingdoms/zulgurub/zulgurub.h => src/server/scripts/eastern_kingdoms/zulgurub/zulgurub.h rename : src/scripts/examples/example_creature.cpp => src/server/scripts/examples/example_creature.cpp rename : src/scripts/examples/example_escort.cpp => src/server/scripts/examples/example_escort.cpp rename : src/scripts/examples/example_gossip_codebox.cpp => src/server/scripts/examples/example_gossip_codebox.cpp rename : src/scripts/examples/example_misc.cpp => src/server/scripts/examples/example_misc.cpp rename : src/scripts/kalimdor/ashenvale.cpp => src/server/scripts/kalimdor/ashenvale.cpp rename : src/scripts/kalimdor/azshara.cpp => src/server/scripts/kalimdor/azshara.cpp rename : src/scripts/kalimdor/azuremyst_isle.cpp => src/server/scripts/kalimdor/azuremyst_isle.cpp rename : src/scripts/kalimdor/blackfathom_depths/blackfathom_deeps.cpp => src/server/scripts/kalimdor/blackfathom_depths/blackfathom_deeps.cpp rename : src/scripts/kalimdor/blackfathom_depths/blackfathom_deeps.h => src/server/scripts/kalimdor/blackfathom_depths/blackfathom_deeps.h rename : src/scripts/kalimdor/blackfathom_depths/boss_aku_mai.cpp => src/server/scripts/kalimdor/blackfathom_depths/boss_aku_mai.cpp rename : src/scripts/kalimdor/blackfathom_depths/boss_gelihast.cpp => src/server/scripts/kalimdor/blackfathom_depths/boss_gelihast.cpp rename : src/scripts/kalimdor/blackfathom_depths/boss_kelris.cpp => src/server/scripts/kalimdor/blackfathom_depths/boss_kelris.cpp rename : src/scripts/kalimdor/blackfathom_depths/instance_blackfathom_deeps.cpp => src/server/scripts/kalimdor/blackfathom_depths/instance_blackfathom_deeps.cpp rename : src/scripts/kalimdor/bloodmyst_isle.cpp => src/server/scripts/kalimdor/bloodmyst_isle.cpp rename : src/scripts/kalimdor/boss_azuregos.cpp => src/server/scripts/kalimdor/boss_azuregos.cpp rename : src/scripts/kalimdor/caverns_of_time/culling_of_stratholme/boss_epoch.cpp => src/server/scripts/kalimdor/caverns_of_time/culling_of_stratholme/boss_epoch.cpp rename : src/scripts/kalimdor/caverns_of_time/culling_of_stratholme/boss_infinite.cpp => src/server/scripts/kalimdor/caverns_of_time/culling_of_stratholme/boss_infinite.cpp rename : src/scripts/kalimdor/caverns_of_time/culling_of_stratholme/boss_mal_ganis.cpp => src/server/scripts/kalimdor/caverns_of_time/culling_of_stratholme/boss_mal_ganis.cpp rename : src/scripts/kalimdor/caverns_of_time/culling_of_stratholme/boss_meathook.cpp => src/server/scripts/kalimdor/caverns_of_time/culling_of_stratholme/boss_meathook.cpp rename : src/scripts/kalimdor/caverns_of_time/culling_of_stratholme/boss_salramm.cpp => src/server/scripts/kalimdor/caverns_of_time/culling_of_stratholme/boss_salramm.cpp rename : src/scripts/kalimdor/caverns_of_time/culling_of_stratholme/culling_of_stratholme.cpp => src/server/scripts/kalimdor/caverns_of_time/culling_of_stratholme/culling_of_stratholme.cpp rename : src/scripts/kalimdor/caverns_of_time/culling_of_stratholme/culling_of_stratholme.h => src/server/scripts/kalimdor/caverns_of_time/culling_of_stratholme/culling_of_stratholme.h rename : src/scripts/kalimdor/caverns_of_time/culling_of_stratholme/instance_culling_of_stratholme.cpp => src/server/scripts/kalimdor/caverns_of_time/culling_of_stratholme/instance_culling_of_stratholme.cpp rename : src/scripts/kalimdor/caverns_of_time/dark_portal/boss_aeonus.cpp => src/server/scripts/kalimdor/caverns_of_time/dark_portal/boss_aeonus.cpp rename : src/scripts/kalimdor/caverns_of_time/dark_portal/boss_chrono_lord_deja.cpp => src/server/scripts/kalimdor/caverns_of_time/dark_portal/boss_chrono_lord_deja.cpp rename : src/scripts/kalimdor/caverns_of_time/dark_portal/boss_temporus.cpp => src/server/scripts/kalimdor/caverns_of_time/dark_portal/boss_temporus.cpp rename : src/scripts/kalimdor/caverns_of_time/dark_portal/dark_portal.cpp => src/server/scripts/kalimdor/caverns_of_time/dark_portal/dark_portal.cpp rename : src/scripts/kalimdor/caverns_of_time/dark_portal/dark_portal.h => src/server/scripts/kalimdor/caverns_of_time/dark_portal/dark_portal.h rename : src/scripts/kalimdor/caverns_of_time/dark_portal/instance_dark_portal.cpp => src/server/scripts/kalimdor/caverns_of_time/dark_portal/instance_dark_portal.cpp rename : src/scripts/kalimdor/caverns_of_time/hyjal/boss_anetheron.cpp => src/server/scripts/kalimdor/caverns_of_time/hyjal/boss_anetheron.cpp rename : src/scripts/kalimdor/caverns_of_time/hyjal/boss_archimonde.cpp => src/server/scripts/kalimdor/caverns_of_time/hyjal/boss_archimonde.cpp rename : src/scripts/kalimdor/caverns_of_time/hyjal/boss_azgalor.cpp => src/server/scripts/kalimdor/caverns_of_time/hyjal/boss_azgalor.cpp rename : src/scripts/kalimdor/caverns_of_time/hyjal/boss_kazrogal.cpp => src/server/scripts/kalimdor/caverns_of_time/hyjal/boss_kazrogal.cpp rename : src/scripts/kalimdor/caverns_of_time/hyjal/boss_rage_winterchill.cpp => src/server/scripts/kalimdor/caverns_of_time/hyjal/boss_rage_winterchill.cpp rename : src/scripts/kalimdor/caverns_of_time/hyjal/hyjal.cpp => src/server/scripts/kalimdor/caverns_of_time/hyjal/hyjal.cpp rename : src/scripts/kalimdor/caverns_of_time/hyjal/hyjal.h => src/server/scripts/kalimdor/caverns_of_time/hyjal/hyjal.h rename : src/scripts/kalimdor/caverns_of_time/hyjal/hyjalAI.cpp => src/server/scripts/kalimdor/caverns_of_time/hyjal/hyjalAI.cpp rename : src/scripts/kalimdor/caverns_of_time/hyjal/hyjalAI.h => src/server/scripts/kalimdor/caverns_of_time/hyjal/hyjalAI.h rename : src/scripts/kalimdor/caverns_of_time/hyjal/hyjal_trash.cpp => src/server/scripts/kalimdor/caverns_of_time/hyjal/hyjal_trash.cpp rename : src/scripts/kalimdor/caverns_of_time/hyjal/hyjal_trash.h => src/server/scripts/kalimdor/caverns_of_time/hyjal/hyjal_trash.h rename : src/scripts/kalimdor/caverns_of_time/hyjal/instance_hyjal.cpp => src/server/scripts/kalimdor/caverns_of_time/hyjal/instance_hyjal.cpp rename : src/scripts/kalimdor/caverns_of_time/old_hillsbrad/boss_captain_skarloc.cpp => src/server/scripts/kalimdor/caverns_of_time/old_hillsbrad/boss_captain_skarloc.cpp rename : src/scripts/kalimdor/caverns_of_time/old_hillsbrad/boss_epoch_hunter.cpp => src/server/scripts/kalimdor/caverns_of_time/old_hillsbrad/boss_epoch_hunter.cpp rename : src/scripts/kalimdor/caverns_of_time/old_hillsbrad/boss_leutenant_drake.cpp => src/server/scripts/kalimdor/caverns_of_time/old_hillsbrad/boss_leutenant_drake.cpp rename : src/scripts/kalimdor/caverns_of_time/old_hillsbrad/instance_old_hillsbrad.cpp => src/server/scripts/kalimdor/caverns_of_time/old_hillsbrad/instance_old_hillsbrad.cpp rename : src/scripts/kalimdor/caverns_of_time/old_hillsbrad/old_hillsbrad.cpp => src/server/scripts/kalimdor/caverns_of_time/old_hillsbrad/old_hillsbrad.cpp rename : src/scripts/kalimdor/caverns_of_time/old_hillsbrad/old_hillsbrad.h => src/server/scripts/kalimdor/caverns_of_time/old_hillsbrad/old_hillsbrad.h rename : src/scripts/kalimdor/darkshore.cpp => src/server/scripts/kalimdor/darkshore.cpp rename : src/scripts/kalimdor/desolace.cpp => src/server/scripts/kalimdor/desolace.cpp rename : src/scripts/kalimdor/durotar.cpp => src/server/scripts/kalimdor/durotar.cpp rename : src/scripts/kalimdor/dustwallow_marsh.cpp => src/server/scripts/kalimdor/dustwallow_marsh.cpp rename : src/scripts/kalimdor/felwood.cpp => src/server/scripts/kalimdor/felwood.cpp rename : src/scripts/kalimdor/feralas.cpp => src/server/scripts/kalimdor/feralas.cpp rename : src/scripts/kalimdor/maraudon/boss_celebras_the_cursed.cpp => src/server/scripts/kalimdor/maraudon/boss_celebras_the_cursed.cpp rename : src/scripts/kalimdor/maraudon/boss_landslide.cpp => src/server/scripts/kalimdor/maraudon/boss_landslide.cpp rename : src/scripts/kalimdor/maraudon/boss_noxxion.cpp => src/server/scripts/kalimdor/maraudon/boss_noxxion.cpp rename : src/scripts/kalimdor/maraudon/boss_princess_theradras.cpp => src/server/scripts/kalimdor/maraudon/boss_princess_theradras.cpp rename : src/scripts/kalimdor/moonglade.cpp => src/server/scripts/kalimdor/moonglade.cpp rename : src/scripts/kalimdor/mulgore.cpp => src/server/scripts/kalimdor/mulgore.cpp rename : src/scripts/kalimdor/onyxias_lair/boss_onyxia.cpp => src/server/scripts/kalimdor/onyxias_lair/boss_onyxia.cpp rename : src/scripts/kalimdor/onyxias_lair/instance_onyxias_lair.cpp => src/server/scripts/kalimdor/onyxias_lair/instance_onyxias_lair.cpp rename : src/scripts/kalimdor/onyxias_lair/onyxias_lair.h => src/server/scripts/kalimdor/onyxias_lair/onyxias_lair.h rename : src/scripts/kalimdor/orgrimmar.cpp => src/server/scripts/kalimdor/orgrimmar.cpp rename : src/scripts/kalimdor/razorfen_downs/boss_amnennar_the_coldbringer.cpp => src/server/scripts/kalimdor/razorfen_downs/boss_amnennar_the_coldbringer.cpp rename : src/scripts/kalimdor/razorfen_downs/instance_razorfen_downs.cpp => src/server/scripts/kalimdor/razorfen_downs/instance_razorfen_downs.cpp rename : src/scripts/kalimdor/razorfen_downs/razorfen_downs.cpp => src/server/scripts/kalimdor/razorfen_downs/razorfen_downs.cpp rename : src/scripts/kalimdor/razorfen_downs/razorfen_downs.h => src/server/scripts/kalimdor/razorfen_downs/razorfen_downs.h rename : src/scripts/kalimdor/razorfen_kraul/instance_razorfen_kraul.cpp => src/server/scripts/kalimdor/razorfen_kraul/instance_razorfen_kraul.cpp rename : src/scripts/kalimdor/razorfen_kraul/razorfen_kraul.cpp => src/server/scripts/kalimdor/razorfen_kraul/razorfen_kraul.cpp rename : src/scripts/kalimdor/razorfen_kraul/razorfen_kraul.h => src/server/scripts/kalimdor/razorfen_kraul/razorfen_kraul.h rename : src/scripts/kalimdor/ruins_of_ahnqiraj/boss_ayamiss.cpp => src/server/scripts/kalimdor/ruins_of_ahnqiraj/boss_ayamiss.cpp rename : src/scripts/kalimdor/ruins_of_ahnqiraj/boss_buru.cpp => src/server/scripts/kalimdor/ruins_of_ahnqiraj/boss_buru.cpp rename : src/scripts/kalimdor/ruins_of_ahnqiraj/boss_kurinnaxx.cpp => src/server/scripts/kalimdor/ruins_of_ahnqiraj/boss_kurinnaxx.cpp rename : src/scripts/kalimdor/ruins_of_ahnqiraj/boss_moam.cpp => src/server/scripts/kalimdor/ruins_of_ahnqiraj/boss_moam.cpp rename : src/scripts/kalimdor/ruins_of_ahnqiraj/boss_ossirian.cpp => src/server/scripts/kalimdor/ruins_of_ahnqiraj/boss_ossirian.cpp rename : src/scripts/kalimdor/ruins_of_ahnqiraj/boss_rajaxx.cpp => src/server/scripts/kalimdor/ruins_of_ahnqiraj/boss_rajaxx.cpp rename : src/scripts/kalimdor/ruins_of_ahnqiraj/instance_ruins_of_ahnqiraj.cpp => src/server/scripts/kalimdor/ruins_of_ahnqiraj/instance_ruins_of_ahnqiraj.cpp rename : src/scripts/kalimdor/ruins_of_ahnqiraj/ruins_of_ahnqiraj.h => src/server/scripts/kalimdor/ruins_of_ahnqiraj/ruins_of_ahnqiraj.h rename : src/scripts/kalimdor/silithus.cpp => src/server/scripts/kalimdor/silithus.cpp rename : src/scripts/kalimdor/stonetalon_mountains.cpp => src/server/scripts/kalimdor/stonetalon_mountains.cpp rename : src/scripts/kalimdor/tanaris.cpp => src/server/scripts/kalimdor/tanaris.cpp rename : src/scripts/kalimdor/teldrassil.cpp => src/server/scripts/kalimdor/teldrassil.cpp rename : src/scripts/kalimdor/temple_of_ahnqiraj/boss_bug_trio.cpp => src/server/scripts/kalimdor/temple_of_ahnqiraj/boss_bug_trio.cpp rename : src/scripts/kalimdor/temple_of_ahnqiraj/boss_cthun.cpp => src/server/scripts/kalimdor/temple_of_ahnqiraj/boss_cthun.cpp rename : src/scripts/kalimdor/temple_of_ahnqiraj/boss_fankriss.cpp => src/server/scripts/kalimdor/temple_of_ahnqiraj/boss_fankriss.cpp rename : src/scripts/kalimdor/temple_of_ahnqiraj/boss_huhuran.cpp => src/server/scripts/kalimdor/temple_of_ahnqiraj/boss_huhuran.cpp rename : src/scripts/kalimdor/temple_of_ahnqiraj/boss_ouro.cpp => src/server/scripts/kalimdor/temple_of_ahnqiraj/boss_ouro.cpp rename : src/scripts/kalimdor/temple_of_ahnqiraj/boss_sartura.cpp => src/server/scripts/kalimdor/temple_of_ahnqiraj/boss_sartura.cpp rename : src/scripts/kalimdor/temple_of_ahnqiraj/boss_skeram.cpp => src/server/scripts/kalimdor/temple_of_ahnqiraj/boss_skeram.cpp rename : src/scripts/kalimdor/temple_of_ahnqiraj/boss_twinemperors.cpp => src/server/scripts/kalimdor/temple_of_ahnqiraj/boss_twinemperors.cpp rename : src/scripts/kalimdor/temple_of_ahnqiraj/boss_viscidus.cpp => src/server/scripts/kalimdor/temple_of_ahnqiraj/boss_viscidus.cpp rename : src/scripts/kalimdor/temple_of_ahnqiraj/instance_temple_of_ahnqiraj.cpp => src/server/scripts/kalimdor/temple_of_ahnqiraj/instance_temple_of_ahnqiraj.cpp rename : src/scripts/kalimdor/temple_of_ahnqiraj/mob_anubisath_sentinel.cpp => src/server/scripts/kalimdor/temple_of_ahnqiraj/mob_anubisath_sentinel.cpp rename : src/scripts/kalimdor/temple_of_ahnqiraj/temple_of_ahnqiraj.h => src/server/scripts/kalimdor/temple_of_ahnqiraj/temple_of_ahnqiraj.h rename : src/scripts/kalimdor/the_barrens.cpp => src/server/scripts/kalimdor/the_barrens.cpp rename : src/scripts/kalimdor/thousand_needles.cpp => src/server/scripts/kalimdor/thousand_needles.cpp rename : src/scripts/kalimdor/thunder_bluff.cpp => src/server/scripts/kalimdor/thunder_bluff.cpp rename : src/scripts/kalimdor/ungoro_crater.cpp => src/server/scripts/kalimdor/ungoro_crater.cpp rename : src/scripts/kalimdor/wailing_caverns/instance_wailing_caverns.cpp => src/server/scripts/kalimdor/wailing_caverns/instance_wailing_caverns.cpp rename : src/scripts/kalimdor/wailing_caverns/wailing_caverns.cpp => src/server/scripts/kalimdor/wailing_caverns/wailing_caverns.cpp rename : src/scripts/kalimdor/wailing_caverns/wailing_caverns.h => src/server/scripts/kalimdor/wailing_caverns/wailing_caverns.h rename : src/scripts/kalimdor/winterspring.cpp => src/server/scripts/kalimdor/winterspring.cpp rename : src/scripts/kalimdor/zulfarrak/instance_zulfarrak.cpp => src/server/scripts/kalimdor/zulfarrak/instance_zulfarrak.cpp rename : src/scripts/kalimdor/zulfarrak/zulfarrak.cpp => src/server/scripts/kalimdor/zulfarrak/zulfarrak.cpp rename : src/scripts/northrend/azjol_nerub/ahnkahet/ahnkahet.h => src/server/scripts/northrend/azjol_nerub/ahnkahet/ahnkahet.h rename : src/scripts/northrend/azjol_nerub/ahnkahet/boss_amanitar.cpp => src/server/scripts/northrend/azjol_nerub/ahnkahet/boss_amanitar.cpp rename : src/scripts/northrend/azjol_nerub/ahnkahet/boss_elder_nadox.cpp => src/server/scripts/northrend/azjol_nerub/ahnkahet/boss_elder_nadox.cpp rename : src/scripts/northrend/azjol_nerub/ahnkahet/boss_herald_volazj.cpp => src/server/scripts/northrend/azjol_nerub/ahnkahet/boss_herald_volazj.cpp rename : src/scripts/northrend/azjol_nerub/ahnkahet/boss_jedoga_shadowseeker.cpp => src/server/scripts/northrend/azjol_nerub/ahnkahet/boss_jedoga_shadowseeker.cpp rename : src/scripts/northrend/azjol_nerub/ahnkahet/boss_prince_taldaram.cpp => src/server/scripts/northrend/azjol_nerub/ahnkahet/boss_prince_taldaram.cpp rename : src/scripts/northrend/azjol_nerub/ahnkahet/instance_ahnkahet.cpp => src/server/scripts/northrend/azjol_nerub/ahnkahet/instance_ahnkahet.cpp rename : src/scripts/northrend/azjol_nerub/azjol_nerub/azjol_nerub.h => src/server/scripts/northrend/azjol_nerub/azjol_nerub/azjol_nerub.h rename : src/scripts/northrend/azjol_nerub/azjol_nerub/boss_anubarak.cpp => src/server/scripts/northrend/azjol_nerub/azjol_nerub/boss_anubarak.cpp rename : src/scripts/northrend/azjol_nerub/azjol_nerub/boss_hadronox.cpp => src/server/scripts/northrend/azjol_nerub/azjol_nerub/boss_hadronox.cpp rename : src/scripts/northrend/azjol_nerub/azjol_nerub/boss_krikthir_the_gatewatcher.cpp => src/server/scripts/northrend/azjol_nerub/azjol_nerub/boss_krikthir_the_gatewatcher.cpp rename : src/scripts/northrend/azjol_nerub/azjol_nerub/instance_azjol_nerub.cpp => src/server/scripts/northrend/azjol_nerub/azjol_nerub/instance_azjol_nerub.cpp rename : src/scripts/northrend/borean_tundra.cpp => src/server/scripts/northrend/borean_tundra.cpp rename : src/scripts/northrend/crusaders_coliseum/trial_of_the_champion/boss_argent_challenge.cpp => src/server/scripts/northrend/crusaders_coliseum/trial_of_the_champion/boss_argent_challenge.cpp rename : src/scripts/northrend/crusaders_coliseum/trial_of_the_champion/boss_black_knight.cpp => src/server/scripts/northrend/crusaders_coliseum/trial_of_the_champion/boss_black_knight.cpp rename : src/scripts/northrend/crusaders_coliseum/trial_of_the_champion/boss_grand_champions.cpp => src/server/scripts/northrend/crusaders_coliseum/trial_of_the_champion/boss_grand_champions.cpp rename : src/scripts/northrend/crusaders_coliseum/trial_of_the_champion/instance_trial_of_the_champion.cpp => src/server/scripts/northrend/crusaders_coliseum/trial_of_the_champion/instance_trial_of_the_champion.cpp rename : src/scripts/northrend/crusaders_coliseum/trial_of_the_champion/trial_of_the_champion.cpp => src/server/scripts/northrend/crusaders_coliseum/trial_of_the_champion/trial_of_the_champion.cpp rename : src/scripts/northrend/crusaders_coliseum/trial_of_the_champion/trial_of_the_champion.h => src/server/scripts/northrend/crusaders_coliseum/trial_of_the_champion/trial_of_the_champion.h rename : src/scripts/northrend/crystalsong_forest.cpp => src/server/scripts/northrend/crystalsong_forest.cpp rename : src/scripts/northrend/dalaran.cpp => src/server/scripts/northrend/dalaran.cpp rename : src/scripts/northrend/dragonblight.cpp => src/server/scripts/northrend/dragonblight.cpp rename : src/scripts/northrend/draktharon_keep/boss_dred.cpp => src/server/scripts/northrend/draktharon_keep/boss_dred.cpp rename : src/scripts/northrend/draktharon_keep/boss_novos.cpp => src/server/scripts/northrend/draktharon_keep/boss_novos.cpp rename : src/scripts/northrend/draktharon_keep/boss_tharon_ja.cpp => src/server/scripts/northrend/draktharon_keep/boss_tharon_ja.cpp rename : src/scripts/northrend/draktharon_keep/boss_trollgore.cpp => src/server/scripts/northrend/draktharon_keep/boss_trollgore.cpp rename : src/scripts/northrend/draktharon_keep/drak_tharon_keep.h => src/server/scripts/northrend/draktharon_keep/drak_tharon_keep.h rename : src/scripts/northrend/draktharon_keep/instance_drak_tharon_keep.cpp => src/server/scripts/northrend/draktharon_keep/instance_drak_tharon_keep.cpp rename : src/scripts/northrend/frozen_halls/forge_of_souls/boss_bronjahm.cpp => src/server/scripts/northrend/frozen_halls/forge_of_souls/boss_bronjahm.cpp rename : src/scripts/northrend/frozen_halls/forge_of_souls/boss_devourer_of_souls.cpp => src/server/scripts/northrend/frozen_halls/forge_of_souls/boss_devourer_of_souls.cpp rename : src/scripts/northrend/frozen_halls/forge_of_souls/forge_of_souls.cpp => src/server/scripts/northrend/frozen_halls/forge_of_souls/forge_of_souls.cpp rename : src/scripts/northrend/frozen_halls/forge_of_souls/forge_of_souls.h => src/server/scripts/northrend/frozen_halls/forge_of_souls/forge_of_souls.h rename : src/scripts/northrend/frozen_halls/forge_of_souls/instance_forge_of_souls.cpp => src/server/scripts/northrend/frozen_halls/forge_of_souls/instance_forge_of_souls.cpp rename : src/scripts/northrend/frozen_halls/halls_of_reflection/boss_falric.cpp => src/server/scripts/northrend/frozen_halls/halls_of_reflection/boss_falric.cpp rename : src/scripts/northrend/frozen_halls/halls_of_reflection/boss_marwyn.cpp => src/server/scripts/northrend/frozen_halls/halls_of_reflection/boss_marwyn.cpp rename : src/scripts/northrend/frozen_halls/halls_of_reflection/halls_of_reflection.cpp => src/server/scripts/northrend/frozen_halls/halls_of_reflection/halls_of_reflection.cpp rename : src/scripts/northrend/frozen_halls/halls_of_reflection/halls_of_reflection.h => src/server/scripts/northrend/frozen_halls/halls_of_reflection/halls_of_reflection.h rename : src/scripts/northrend/frozen_halls/halls_of_reflection/instance_halls_of_reflection.cpp => src/server/scripts/northrend/frozen_halls/halls_of_reflection/instance_halls_of_reflection.cpp rename : src/scripts/northrend/frozen_halls/pit_of_saron/boss_forgemaster_garfrost.cpp => src/server/scripts/northrend/frozen_halls/pit_of_saron/boss_forgemaster_garfrost.cpp rename : src/scripts/northrend/frozen_halls/pit_of_saron/boss_krickandick.cpp => src/server/scripts/northrend/frozen_halls/pit_of_saron/boss_krickandick.cpp rename : src/scripts/northrend/frozen_halls/pit_of_saron/boss_scourgelord_tyrannus.cpp => src/server/scripts/northrend/frozen_halls/pit_of_saron/boss_scourgelord_tyrannus.cpp rename : src/scripts/northrend/frozen_halls/pit_of_saron/instance_pit_of_saron.cpp => src/server/scripts/northrend/frozen_halls/pit_of_saron/instance_pit_of_saron.cpp rename : src/scripts/northrend/frozen_halls/pit_of_saron/pit_of_saron.cpp => src/server/scripts/northrend/frozen_halls/pit_of_saron/pit_of_saron.cpp rename : src/scripts/northrend/frozen_halls/pit_of_saron/pit_of_saron.h => src/server/scripts/northrend/frozen_halls/pit_of_saron/pit_of_saron.h rename : src/scripts/northrend/grizzly_hills.cpp => src/server/scripts/northrend/grizzly_hills.cpp rename : src/scripts/northrend/gundrak/boss_drakkari_colossus.cpp => src/server/scripts/northrend/gundrak/boss_drakkari_colossus.cpp rename : src/scripts/northrend/gundrak/boss_eck.cpp => src/server/scripts/northrend/gundrak/boss_eck.cpp rename : src/scripts/northrend/gundrak/boss_gal_darah.cpp => src/server/scripts/northrend/gundrak/boss_gal_darah.cpp rename : src/scripts/northrend/gundrak/boss_moorabi.cpp => src/server/scripts/northrend/gundrak/boss_moorabi.cpp rename : src/scripts/northrend/gundrak/boss_slad_ran.cpp => src/server/scripts/northrend/gundrak/boss_slad_ran.cpp rename : src/scripts/northrend/gundrak/gundrak.h => src/server/scripts/northrend/gundrak/gundrak.h rename : src/scripts/northrend/gundrak/instance_gundrak.cpp => src/server/scripts/northrend/gundrak/instance_gundrak.cpp rename : src/scripts/northrend/howling_fjord.cpp => src/server/scripts/northrend/howling_fjord.cpp rename : src/scripts/northrend/icecrown.cpp => src/server/scripts/northrend/icecrown.cpp rename : src/scripts/northrend/naxxramas/boss_anubrekhan.cpp => src/server/scripts/northrend/naxxramas/boss_anubrekhan.cpp rename : src/scripts/northrend/naxxramas/boss_faerlina.cpp => src/server/scripts/northrend/naxxramas/boss_faerlina.cpp rename : src/scripts/northrend/naxxramas/boss_four_horsemen.cpp => src/server/scripts/northrend/naxxramas/boss_four_horsemen.cpp rename : src/scripts/northrend/naxxramas/boss_gluth.cpp => src/server/scripts/northrend/naxxramas/boss_gluth.cpp rename : src/scripts/northrend/naxxramas/boss_gothik.cpp => src/server/scripts/northrend/naxxramas/boss_gothik.cpp rename : src/scripts/northrend/naxxramas/boss_grobbulus.cpp => src/server/scripts/northrend/naxxramas/boss_grobbulus.cpp rename : src/scripts/northrend/naxxramas/boss_heigan.cpp => src/server/scripts/northrend/naxxramas/boss_heigan.cpp rename : src/scripts/northrend/naxxramas/boss_highlord_mograine.cpp => src/server/scripts/northrend/naxxramas/boss_highlord_mograine.cpp rename : src/scripts/northrend/naxxramas/boss_kelthuzad.cpp => src/server/scripts/northrend/naxxramas/boss_kelthuzad.cpp rename : src/scripts/northrend/naxxramas/boss_loatheb.cpp => src/server/scripts/northrend/naxxramas/boss_loatheb.cpp rename : src/scripts/northrend/naxxramas/boss_maexxna.cpp => src/server/scripts/northrend/naxxramas/boss_maexxna.cpp rename : src/scripts/northrend/naxxramas/boss_noth.cpp => src/server/scripts/northrend/naxxramas/boss_noth.cpp rename : src/scripts/northrend/naxxramas/boss_patchwerk.cpp => src/server/scripts/northrend/naxxramas/boss_patchwerk.cpp rename : src/scripts/northrend/naxxramas/boss_razuvious.cpp => src/server/scripts/northrend/naxxramas/boss_razuvious.cpp rename : src/scripts/northrend/naxxramas/boss_sapphiron.cpp => src/server/scripts/northrend/naxxramas/boss_sapphiron.cpp rename : src/scripts/northrend/naxxramas/boss_thaddius.cpp => src/server/scripts/northrend/naxxramas/boss_thaddius.cpp rename : src/scripts/northrend/naxxramas/instance_naxxramas.cpp => src/server/scripts/northrend/naxxramas/instance_naxxramas.cpp rename : src/scripts/northrend/naxxramas/naxxramas.h => src/server/scripts/northrend/naxxramas/naxxramas.h rename : src/scripts/northrend/nexus/eye_of_eternity/boss_malygos.cpp => src/server/scripts/northrend/nexus/eye_of_eternity/boss_malygos.cpp rename : src/scripts/northrend/nexus/eye_of_eternity/eye_of_eternity.h => src/server/scripts/northrend/nexus/eye_of_eternity/eye_of_eternity.h rename : src/scripts/northrend/nexus/eye_of_eternity/instance_eye_of_eternity.cpp => src/server/scripts/northrend/nexus/eye_of_eternity/instance_eye_of_eternity.cpp rename : src/scripts/northrend/nexus/nexus/boss_anomalus.cpp => src/server/scripts/northrend/nexus/nexus/boss_anomalus.cpp rename : src/scripts/northrend/nexus/nexus/boss_keristrasza.cpp => src/server/scripts/northrend/nexus/nexus/boss_keristrasza.cpp rename : src/scripts/northrend/nexus/nexus/boss_magus_telestra.cpp => src/server/scripts/northrend/nexus/nexus/boss_magus_telestra.cpp rename : src/scripts/northrend/nexus/nexus/boss_ormorok.cpp => src/server/scripts/northrend/nexus/nexus/boss_ormorok.cpp rename : src/scripts/northrend/nexus/nexus/commander_kolurg.cpp => src/server/scripts/northrend/nexus/nexus/commander_kolurg.cpp rename : src/scripts/northrend/nexus/nexus/commander_stoutbeard.cpp => src/server/scripts/northrend/nexus/nexus/commander_stoutbeard.cpp rename : src/scripts/northrend/nexus/nexus/instance_nexus.cpp => src/server/scripts/northrend/nexus/nexus/instance_nexus.cpp rename : src/scripts/northrend/nexus/nexus/nexus.h => src/server/scripts/northrend/nexus/nexus/nexus.h rename : src/scripts/northrend/nexus/oculus/boss_drakos.cpp => src/server/scripts/northrend/nexus/oculus/boss_drakos.cpp rename : src/scripts/northrend/nexus/oculus/boss_eregos.cpp => src/server/scripts/northrend/nexus/oculus/boss_eregos.cpp rename : src/scripts/northrend/nexus/oculus/boss_urom.cpp => src/server/scripts/northrend/nexus/oculus/boss_urom.cpp rename : src/scripts/northrend/nexus/oculus/boss_varos.cpp => src/server/scripts/northrend/nexus/oculus/boss_varos.cpp rename : src/scripts/northrend/nexus/oculus/instance_oculus.cpp => src/server/scripts/northrend/nexus/oculus/instance_oculus.cpp rename : src/scripts/northrend/nexus/oculus/oculus.cpp => src/server/scripts/northrend/nexus/oculus/oculus.cpp rename : src/scripts/northrend/nexus/oculus/oculus.h => src/server/scripts/northrend/nexus/oculus/oculus.h rename : src/scripts/northrend/obsidian_sanctum/boss_sartharion.cpp => src/server/scripts/northrend/obsidian_sanctum/boss_sartharion.cpp rename : src/scripts/northrend/obsidian_sanctum/instance_obsidian_sanctum.cpp => src/server/scripts/northrend/obsidian_sanctum/instance_obsidian_sanctum.cpp rename : src/scripts/northrend/obsidian_sanctum/obsidian_sanctum.h => src/server/scripts/northrend/obsidian_sanctum/obsidian_sanctum.h rename : src/scripts/northrend/sholazar_basin.cpp => src/server/scripts/northrend/sholazar_basin.cpp rename : src/scripts/northrend/storm_peaks.cpp => src/server/scripts/northrend/storm_peaks.cpp rename : src/scripts/northrend/ulduar/halls_of_lightning/boss_bjarngrim.cpp => src/server/scripts/northrend/ulduar/halls_of_lightning/boss_bjarngrim.cpp rename : src/scripts/northrend/ulduar/halls_of_lightning/boss_ionar.cpp => src/server/scripts/northrend/ulduar/halls_of_lightning/boss_ionar.cpp rename : src/scripts/northrend/ulduar/halls_of_lightning/boss_loken.cpp => src/server/scripts/northrend/ulduar/halls_of_lightning/boss_loken.cpp rename : src/scripts/northrend/ulduar/halls_of_lightning/boss_volkhan.cpp => src/server/scripts/northrend/ulduar/halls_of_lightning/boss_volkhan.cpp rename : src/scripts/northrend/ulduar/halls_of_lightning/halls_of_lightning.h => src/server/scripts/northrend/ulduar/halls_of_lightning/halls_of_lightning.h rename : src/scripts/northrend/ulduar/halls_of_lightning/instance_halls_of_lightning.cpp => src/server/scripts/northrend/ulduar/halls_of_lightning/instance_halls_of_lightning.cpp rename : src/scripts/northrend/ulduar/halls_of_stone/boss_krystallus.cpp => src/server/scripts/northrend/ulduar/halls_of_stone/boss_krystallus.cpp rename : src/scripts/northrend/ulduar/halls_of_stone/boss_maiden_of_grief.cpp => src/server/scripts/northrend/ulduar/halls_of_stone/boss_maiden_of_grief.cpp rename : src/scripts/northrend/ulduar/halls_of_stone/boss_sjonnir.cpp => src/server/scripts/northrend/ulduar/halls_of_stone/boss_sjonnir.cpp rename : src/scripts/northrend/ulduar/halls_of_stone/halls_of_stone.cpp => src/server/scripts/northrend/ulduar/halls_of_stone/halls_of_stone.cpp rename : src/scripts/northrend/ulduar/halls_of_stone/halls_of_stone.h => src/server/scripts/northrend/ulduar/halls_of_stone/halls_of_stone.h rename : src/scripts/northrend/ulduar/halls_of_stone/instance_halls_of_stone.cpp => src/server/scripts/northrend/ulduar/halls_of_stone/instance_halls_of_stone.cpp rename : src/scripts/northrend/ulduar/ulduar/boss_algalon.cpp => src/server/scripts/northrend/ulduar/ulduar/boss_algalon.cpp rename : src/scripts/northrend/ulduar/ulduar/boss_assembly_of_iron.cpp => src/server/scripts/northrend/ulduar/ulduar/boss_assembly_of_iron.cpp rename : src/scripts/northrend/ulduar/ulduar/boss_auriaya.cpp => src/server/scripts/northrend/ulduar/ulduar/boss_auriaya.cpp rename : src/scripts/northrend/ulduar/ulduar/boss_flame_leviathan.cpp => src/server/scripts/northrend/ulduar/ulduar/boss_flame_leviathan.cpp rename : src/scripts/northrend/ulduar/ulduar/boss_freya.cpp => src/server/scripts/northrend/ulduar/ulduar/boss_freya.cpp rename : src/scripts/northrend/ulduar/ulduar/boss_general_vezax.cpp => src/server/scripts/northrend/ulduar/ulduar/boss_general_vezax.cpp rename : src/scripts/northrend/ulduar/ulduar/boss_hodir.cpp => src/server/scripts/northrend/ulduar/ulduar/boss_hodir.cpp rename : src/scripts/northrend/ulduar/ulduar/boss_ignis.cpp => src/server/scripts/northrend/ulduar/ulduar/boss_ignis.cpp rename : src/scripts/northrend/ulduar/ulduar/boss_kologarn.cpp => src/server/scripts/northrend/ulduar/ulduar/boss_kologarn.cpp rename : src/scripts/northrend/ulduar/ulduar/boss_mimiron.cpp => src/server/scripts/northrend/ulduar/ulduar/boss_mimiron.cpp rename : src/scripts/northrend/ulduar/ulduar/boss_razorscale.cpp => src/server/scripts/northrend/ulduar/ulduar/boss_razorscale.cpp rename : src/scripts/northrend/ulduar/ulduar/boss_thorim.cpp => src/server/scripts/northrend/ulduar/ulduar/boss_thorim.cpp rename : src/scripts/northrend/ulduar/ulduar/boss_xt002.cpp => src/server/scripts/northrend/ulduar/ulduar/boss_xt002.cpp rename : src/scripts/northrend/ulduar/ulduar/boss_yoggsaron.cpp => src/server/scripts/northrend/ulduar/ulduar/boss_yoggsaron.cpp rename : src/scripts/northrend/ulduar/ulduar/instance_ulduar.cpp => src/server/scripts/northrend/ulduar/ulduar/instance_ulduar.cpp rename : src/scripts/northrend/ulduar/ulduar/ulduar.h => src/server/scripts/northrend/ulduar/ulduar/ulduar.h rename : src/scripts/northrend/ulduar/ulduar/ulduar_teleporter.cpp => src/server/scripts/northrend/ulduar/ulduar/ulduar_teleporter.cpp rename : src/scripts/northrend/utgarde_keep/utgarde_keep/boss_ingvar_the_plunderer.cpp => src/server/scripts/northrend/utgarde_keep/utgarde_keep/boss_ingvar_the_plunderer.cpp rename : src/scripts/northrend/utgarde_keep/utgarde_keep/boss_keleseth.cpp => src/server/scripts/northrend/utgarde_keep/utgarde_keep/boss_keleseth.cpp rename : src/scripts/northrend/utgarde_keep/utgarde_keep/boss_skarvald_dalronn.cpp => src/server/scripts/northrend/utgarde_keep/utgarde_keep/boss_skarvald_dalronn.cpp rename : src/scripts/northrend/utgarde_keep/utgarde_keep/instance_utgarde_keep.cpp => src/server/scripts/northrend/utgarde_keep/utgarde_keep/instance_utgarde_keep.cpp rename : src/scripts/northrend/utgarde_keep/utgarde_keep/utgarde_keep.cpp => src/server/scripts/northrend/utgarde_keep/utgarde_keep/utgarde_keep.cpp rename : src/scripts/northrend/utgarde_keep/utgarde_keep/utgarde_keep.h => src/server/scripts/northrend/utgarde_keep/utgarde_keep/utgarde_keep.h rename : src/scripts/northrend/utgarde_keep/utgarde_pinnacle/boss_palehoof.cpp => src/server/scripts/northrend/utgarde_keep/utgarde_pinnacle/boss_palehoof.cpp rename : src/scripts/northrend/utgarde_keep/utgarde_pinnacle/boss_skadi.cpp => src/server/scripts/northrend/utgarde_keep/utgarde_pinnacle/boss_skadi.cpp rename : src/scripts/northrend/utgarde_keep/utgarde_pinnacle/boss_svala.cpp => src/server/scripts/northrend/utgarde_keep/utgarde_pinnacle/boss_svala.cpp rename : src/scripts/northrend/utgarde_keep/utgarde_pinnacle/boss_ymiron.cpp => src/server/scripts/northrend/utgarde_keep/utgarde_pinnacle/boss_ymiron.cpp rename : src/scripts/northrend/utgarde_keep/utgarde_pinnacle/instance_pinnacle.cpp => src/server/scripts/northrend/utgarde_keep/utgarde_pinnacle/instance_pinnacle.cpp rename : src/scripts/northrend/utgarde_keep/utgarde_pinnacle/utgarde_pinnacle.h => src/server/scripts/northrend/utgarde_keep/utgarde_pinnacle/utgarde_pinnacle.h rename : src/scripts/northrend/vault_of_archavon/boss_archavon.cpp => src/server/scripts/northrend/vault_of_archavon/boss_archavon.cpp rename : src/scripts/northrend/vault_of_archavon/boss_emalon.cpp => src/server/scripts/northrend/vault_of_archavon/boss_emalon.cpp rename : src/scripts/northrend/vault_of_archavon/boss_koralon.cpp => src/server/scripts/northrend/vault_of_archavon/boss_koralon.cpp rename : src/scripts/northrend/vault_of_archavon/boss_toravon.cpp => src/server/scripts/northrend/vault_of_archavon/boss_toravon.cpp rename : src/scripts/northrend/vault_of_archavon/instance_vault_of_archavon.cpp => src/server/scripts/northrend/vault_of_archavon/instance_vault_of_archavon.cpp rename : src/scripts/northrend/vault_of_archavon/vault_of_archavon.h => src/server/scripts/northrend/vault_of_archavon/vault_of_archavon.h rename : src/scripts/northrend/violet_hold/boss_cyanigosa.cpp => src/server/scripts/northrend/violet_hold/boss_cyanigosa.cpp rename : src/scripts/northrend/violet_hold/boss_erekem.cpp => src/server/scripts/northrend/violet_hold/boss_erekem.cpp rename : src/scripts/northrend/violet_hold/boss_ichoron.cpp => src/server/scripts/northrend/violet_hold/boss_ichoron.cpp rename : src/scripts/northrend/violet_hold/boss_lavanthor.cpp => src/server/scripts/northrend/violet_hold/boss_lavanthor.cpp rename : src/scripts/northrend/violet_hold/boss_moragg.cpp => src/server/scripts/northrend/violet_hold/boss_moragg.cpp rename : src/scripts/northrend/violet_hold/boss_xevozz.cpp => src/server/scripts/northrend/violet_hold/boss_xevozz.cpp rename : src/scripts/northrend/violet_hold/boss_zuramat.cpp => src/server/scripts/northrend/violet_hold/boss_zuramat.cpp rename : src/scripts/northrend/violet_hold/instance_violet_hold.cpp => src/server/scripts/northrend/violet_hold/instance_violet_hold.cpp rename : src/scripts/northrend/violet_hold/violet_hold.cpp => src/server/scripts/northrend/violet_hold/violet_hold.cpp rename : src/scripts/northrend/violet_hold/violet_hold.h => src/server/scripts/northrend/violet_hold/violet_hold.h rename : src/scripts/northrend/zuldrak.cpp => src/server/scripts/northrend/zuldrak.cpp rename : src/scripts/outland/auchindoun/auchenai_crypts/boss_exarch_maladaar.cpp => src/server/scripts/outland/auchindoun/auchenai_crypts/boss_exarch_maladaar.cpp rename : src/scripts/outland/auchindoun/auchenai_crypts/boss_shirrak_the_dead_watcher.cpp => src/server/scripts/outland/auchindoun/auchenai_crypts/boss_shirrak_the_dead_watcher.cpp rename : src/scripts/outland/auchindoun/mana_tombs/boss_nexusprince_shaffar.cpp => src/server/scripts/outland/auchindoun/mana_tombs/boss_nexusprince_shaffar.cpp rename : src/scripts/outland/auchindoun/mana_tombs/boss_pandemonius.cpp => src/server/scripts/outland/auchindoun/mana_tombs/boss_pandemonius.cpp rename : src/scripts/outland/auchindoun/sethekk_halls/boss_darkweaver_syth.cpp => src/server/scripts/outland/auchindoun/sethekk_halls/boss_darkweaver_syth.cpp rename : src/scripts/outland/auchindoun/sethekk_halls/boss_tailonking_ikiss.cpp => src/server/scripts/outland/auchindoun/sethekk_halls/boss_tailonking_ikiss.cpp rename : src/scripts/outland/auchindoun/sethekk_halls/instance_sethekk_halls.cpp => src/server/scripts/outland/auchindoun/sethekk_halls/instance_sethekk_halls.cpp rename : src/scripts/outland/auchindoun/sethekk_halls/sethekk_halls.h => src/server/scripts/outland/auchindoun/sethekk_halls/sethekk_halls.h rename : src/scripts/outland/auchindoun/shadow_labyrinth/boss_ambassador_hellmaw.cpp => src/server/scripts/outland/auchindoun/shadow_labyrinth/boss_ambassador_hellmaw.cpp rename : src/scripts/outland/auchindoun/shadow_labyrinth/boss_blackheart_the_inciter.cpp => src/server/scripts/outland/auchindoun/shadow_labyrinth/boss_blackheart_the_inciter.cpp rename : src/scripts/outland/auchindoun/shadow_labyrinth/boss_grandmaster_vorpil.cpp => src/server/scripts/outland/auchindoun/shadow_labyrinth/boss_grandmaster_vorpil.cpp rename : src/scripts/outland/auchindoun/shadow_labyrinth/boss_murmur.cpp => src/server/scripts/outland/auchindoun/shadow_labyrinth/boss_murmur.cpp rename : src/scripts/outland/auchindoun/shadow_labyrinth/instance_shadow_labyrinth.cpp => src/server/scripts/outland/auchindoun/shadow_labyrinth/instance_shadow_labyrinth.cpp rename : src/scripts/outland/auchindoun/shadow_labyrinth/shadow_labyrinth.h => src/server/scripts/outland/auchindoun/shadow_labyrinth/shadow_labyrinth.h rename : src/scripts/outland/black_temple/black_temple.cpp => src/server/scripts/outland/black_temple/black_temple.cpp rename : src/scripts/outland/black_temple/black_temple.h => src/server/scripts/outland/black_temple/black_temple.h rename : src/scripts/outland/black_temple/boss_bloodboil.cpp => src/server/scripts/outland/black_temple/boss_bloodboil.cpp rename : src/scripts/outland/black_temple/boss_illidan.cpp => src/server/scripts/outland/black_temple/boss_illidan.cpp rename : src/scripts/outland/black_temple/boss_mother_shahraz.cpp => src/server/scripts/outland/black_temple/boss_mother_shahraz.cpp rename : src/scripts/outland/black_temple/boss_reliquary_of_souls.cpp => src/server/scripts/outland/black_temple/boss_reliquary_of_souls.cpp rename : src/scripts/outland/black_temple/boss_shade_of_akama.cpp => src/server/scripts/outland/black_temple/boss_shade_of_akama.cpp rename : src/scripts/outland/black_temple/boss_supremus.cpp => src/server/scripts/outland/black_temple/boss_supremus.cpp rename : src/scripts/outland/black_temple/boss_teron_gorefiend.cpp => src/server/scripts/outland/black_temple/boss_teron_gorefiend.cpp rename : src/scripts/outland/black_temple/boss_warlord_najentus.cpp => src/server/scripts/outland/black_temple/boss_warlord_najentus.cpp rename : src/scripts/outland/black_temple/illidari_council.cpp => src/server/scripts/outland/black_temple/illidari_council.cpp rename : src/scripts/outland/black_temple/instance_black_temple.cpp => src/server/scripts/outland/black_temple/instance_black_temple.cpp rename : src/scripts/outland/blades_edge_mountains.cpp => src/server/scripts/outland/blades_edge_mountains.cpp rename : src/scripts/outland/boss_doomlord_kazzak.cpp => src/server/scripts/outland/boss_doomlord_kazzak.cpp rename : src/scripts/outland/boss_doomwalker.cpp => src/server/scripts/outland/boss_doomwalker.cpp rename : src/scripts/outland/coilfang_resevoir/serpent_shrine/boss_fathomlord_karathress.cpp => src/server/scripts/outland/coilfang_resevoir/serpent_shrine/boss_fathomlord_karathress.cpp rename : src/scripts/outland/coilfang_resevoir/serpent_shrine/boss_hydross_the_unstable.cpp => src/server/scripts/outland/coilfang_resevoir/serpent_shrine/boss_hydross_the_unstable.cpp rename : src/scripts/outland/coilfang_resevoir/serpent_shrine/boss_lady_vashj.cpp => src/server/scripts/outland/coilfang_resevoir/serpent_shrine/boss_lady_vashj.cpp rename : src/scripts/outland/coilfang_resevoir/serpent_shrine/boss_leotheras_the_blind.cpp => src/server/scripts/outland/coilfang_resevoir/serpent_shrine/boss_leotheras_the_blind.cpp rename : src/scripts/outland/coilfang_resevoir/serpent_shrine/boss_lurker_below.cpp => src/server/scripts/outland/coilfang_resevoir/serpent_shrine/boss_lurker_below.cpp rename : src/scripts/outland/coilfang_resevoir/serpent_shrine/boss_morogrim_tidewalker.cpp => src/server/scripts/outland/coilfang_resevoir/serpent_shrine/boss_morogrim_tidewalker.cpp rename : src/scripts/outland/coilfang_resevoir/serpent_shrine/instance_serpent_shrine.cpp => src/server/scripts/outland/coilfang_resevoir/serpent_shrine/instance_serpent_shrine.cpp rename : src/scripts/outland/coilfang_resevoir/serpent_shrine/serpent_shrine.h => src/server/scripts/outland/coilfang_resevoir/serpent_shrine/serpent_shrine.h rename : src/scripts/outland/coilfang_resevoir/steam_vault/boss_hydromancer_thespia.cpp => src/server/scripts/outland/coilfang_resevoir/steam_vault/boss_hydromancer_thespia.cpp rename : src/scripts/outland/coilfang_resevoir/steam_vault/boss_mekgineer_steamrigger.cpp => src/server/scripts/outland/coilfang_resevoir/steam_vault/boss_mekgineer_steamrigger.cpp rename : src/scripts/outland/coilfang_resevoir/steam_vault/boss_warlord_kalithresh.cpp => src/server/scripts/outland/coilfang_resevoir/steam_vault/boss_warlord_kalithresh.cpp rename : src/scripts/outland/coilfang_resevoir/steam_vault/instance_steam_vault.cpp => src/server/scripts/outland/coilfang_resevoir/steam_vault/instance_steam_vault.cpp rename : src/scripts/outland/coilfang_resevoir/steam_vault/steam_vault.h => src/server/scripts/outland/coilfang_resevoir/steam_vault/steam_vault.h rename : src/scripts/outland/coilfang_resevoir/underbog/boss_hungarfen.cpp => src/server/scripts/outland/coilfang_resevoir/underbog/boss_hungarfen.cpp rename : src/scripts/outland/coilfang_resevoir/underbog/boss_the_black_stalker.cpp => src/server/scripts/outland/coilfang_resevoir/underbog/boss_the_black_stalker.cpp rename : src/scripts/outland/gruuls_lair/boss_gruul.cpp => src/server/scripts/outland/gruuls_lair/boss_gruul.cpp rename : src/scripts/outland/gruuls_lair/boss_high_king_maulgar.cpp => src/server/scripts/outland/gruuls_lair/boss_high_king_maulgar.cpp rename : src/scripts/outland/gruuls_lair/gruuls_lair.h => src/server/scripts/outland/gruuls_lair/gruuls_lair.h rename : src/scripts/outland/gruuls_lair/instance_gruuls_lair.cpp => src/server/scripts/outland/gruuls_lair/instance_gruuls_lair.cpp rename : src/scripts/outland/hellfire_citadel/blood_furnace/blood_furnace.h => src/server/scripts/outland/hellfire_citadel/blood_furnace/blood_furnace.h rename : src/scripts/outland/hellfire_citadel/blood_furnace/boss_broggok.cpp => src/server/scripts/outland/hellfire_citadel/blood_furnace/boss_broggok.cpp rename : src/scripts/outland/hellfire_citadel/blood_furnace/boss_kelidan_the_breaker.cpp => src/server/scripts/outland/hellfire_citadel/blood_furnace/boss_kelidan_the_breaker.cpp rename : src/scripts/outland/hellfire_citadel/blood_furnace/boss_the_maker.cpp => src/server/scripts/outland/hellfire_citadel/blood_furnace/boss_the_maker.cpp rename : src/scripts/outland/hellfire_citadel/blood_furnace/instance_blood_furnace.cpp => src/server/scripts/outland/hellfire_citadel/blood_furnace/instance_blood_furnace.cpp rename : src/scripts/outland/hellfire_citadel/hellfire_ramparts/boss_omor_the_unscarred.cpp => src/server/scripts/outland/hellfire_citadel/hellfire_ramparts/boss_omor_the_unscarred.cpp rename : src/scripts/outland/hellfire_citadel/hellfire_ramparts/boss_vazruden_the_herald.cpp => src/server/scripts/outland/hellfire_citadel/hellfire_ramparts/boss_vazruden_the_herald.cpp rename : src/scripts/outland/hellfire_citadel/hellfire_ramparts/boss_watchkeeper_gargolmar.cpp => src/server/scripts/outland/hellfire_citadel/hellfire_ramparts/boss_watchkeeper_gargolmar.cpp rename : src/scripts/outland/hellfire_citadel/hellfire_ramparts/hellfire_ramparts.h => src/server/scripts/outland/hellfire_citadel/hellfire_ramparts/hellfire_ramparts.h rename : src/scripts/outland/hellfire_citadel/hellfire_ramparts/instance_hellfire_ramparts.cpp => src/server/scripts/outland/hellfire_citadel/hellfire_ramparts/instance_hellfire_ramparts.cpp rename : src/scripts/outland/hellfire_citadel/magtheridons_lair/boss_magtheridon.cpp => src/server/scripts/outland/hellfire_citadel/magtheridons_lair/boss_magtheridon.cpp rename : src/scripts/outland/hellfire_citadel/magtheridons_lair/instance_magtheridons_lair.cpp => src/server/scripts/outland/hellfire_citadel/magtheridons_lair/instance_magtheridons_lair.cpp rename : src/scripts/outland/hellfire_citadel/magtheridons_lair/magtheridons_lair.h => src/server/scripts/outland/hellfire_citadel/magtheridons_lair/magtheridons_lair.h rename : src/scripts/outland/hellfire_citadel/shattered_halls/boss_nethekurse.cpp => src/server/scripts/outland/hellfire_citadel/shattered_halls/boss_nethekurse.cpp rename : src/scripts/outland/hellfire_citadel/shattered_halls/boss_warbringer_omrogg.cpp => src/server/scripts/outland/hellfire_citadel/shattered_halls/boss_warbringer_omrogg.cpp rename : src/scripts/outland/hellfire_citadel/shattered_halls/boss_warchief_kargath_bladefist.cpp => src/server/scripts/outland/hellfire_citadel/shattered_halls/boss_warchief_kargath_bladefist.cpp rename : src/scripts/outland/hellfire_citadel/shattered_halls/instance_shattered_halls.cpp => src/server/scripts/outland/hellfire_citadel/shattered_halls/instance_shattered_halls.cpp rename : src/scripts/outland/hellfire_citadel/shattered_halls/shattered_halls.h => src/server/scripts/outland/hellfire_citadel/shattered_halls/shattered_halls.h rename : src/scripts/outland/hellfire_peninsula.cpp => src/server/scripts/outland/hellfire_peninsula.cpp rename : src/scripts/outland/nagrand.cpp => src/server/scripts/outland/nagrand.cpp rename : src/scripts/outland/netherstorm.cpp => src/server/scripts/outland/netherstorm.cpp rename : src/scripts/outland/shadowmoon_valley.cpp => src/server/scripts/outland/shadowmoon_valley.cpp rename : src/scripts/outland/shattrath_city.cpp => src/server/scripts/outland/shattrath_city.cpp rename : src/scripts/outland/tempest_keep/arcatraz/arcatraz.cpp => src/server/scripts/outland/tempest_keep/arcatraz/arcatraz.cpp rename : src/scripts/outland/tempest_keep/arcatraz/arcatraz.h => src/server/scripts/outland/tempest_keep/arcatraz/arcatraz.h rename : src/scripts/outland/tempest_keep/arcatraz/boss_harbinger_skyriss.cpp => src/server/scripts/outland/tempest_keep/arcatraz/boss_harbinger_skyriss.cpp rename : src/scripts/outland/tempest_keep/arcatraz/instance_arcatraz.cpp => src/server/scripts/outland/tempest_keep/arcatraz/instance_arcatraz.cpp rename : src/scripts/outland/tempest_keep/botanica/boss_high_botanist_freywinn.cpp => src/server/scripts/outland/tempest_keep/botanica/boss_high_botanist_freywinn.cpp rename : src/scripts/outland/tempest_keep/botanica/boss_laj.cpp => src/server/scripts/outland/tempest_keep/botanica/boss_laj.cpp rename : src/scripts/outland/tempest_keep/botanica/boss_warp_splinter.cpp => src/server/scripts/outland/tempest_keep/botanica/boss_warp_splinter.cpp rename : src/scripts/outland/tempest_keep/the_eye/boss_alar.cpp => src/server/scripts/outland/tempest_keep/the_eye/boss_alar.cpp rename : src/scripts/outland/tempest_keep/the_eye/boss_astromancer.cpp => src/server/scripts/outland/tempest_keep/the_eye/boss_astromancer.cpp rename : src/scripts/outland/tempest_keep/the_eye/boss_kaelthas.cpp => src/server/scripts/outland/tempest_keep/the_eye/boss_kaelthas.cpp rename : src/scripts/outland/tempest_keep/the_eye/boss_void_reaver.cpp => src/server/scripts/outland/tempest_keep/the_eye/boss_void_reaver.cpp rename : src/scripts/outland/tempest_keep/the_eye/instance_the_eye.cpp => src/server/scripts/outland/tempest_keep/the_eye/instance_the_eye.cpp rename : src/scripts/outland/tempest_keep/the_eye/the_eye.cpp => src/server/scripts/outland/tempest_keep/the_eye/the_eye.cpp rename : src/scripts/outland/tempest_keep/the_eye/the_eye.h => src/server/scripts/outland/tempest_keep/the_eye/the_eye.h rename : src/scripts/outland/tempest_keep/the_mechanar/boss_gatewatcher_gyrokill.cpp => src/server/scripts/outland/tempest_keep/the_mechanar/boss_gatewatcher_gyrokill.cpp rename : src/scripts/outland/tempest_keep/the_mechanar/boss_gatewatcher_ironhand.cpp => src/server/scripts/outland/tempest_keep/the_mechanar/boss_gatewatcher_ironhand.cpp rename : src/scripts/outland/tempest_keep/the_mechanar/boss_nethermancer_sepethrea.cpp => src/server/scripts/outland/tempest_keep/the_mechanar/boss_nethermancer_sepethrea.cpp rename : src/scripts/outland/tempest_keep/the_mechanar/boss_pathaleon_the_calculator.cpp => src/server/scripts/outland/tempest_keep/the_mechanar/boss_pathaleon_the_calculator.cpp rename : src/scripts/outland/tempest_keep/the_mechanar/instance_mechanar.cpp => src/server/scripts/outland/tempest_keep/the_mechanar/instance_mechanar.cpp rename : src/scripts/outland/tempest_keep/the_mechanar/mechanar.h => src/server/scripts/outland/tempest_keep/the_mechanar/mechanar.h rename : src/scripts/outland/terokkar_forest.cpp => src/server/scripts/outland/terokkar_forest.cpp rename : src/scripts/outland/zangarmarsh.cpp => src/server/scripts/outland/zangarmarsh.cpp rename : src/scripts/world/areatrigger_scripts.cpp => src/server/scripts/world/areatrigger_scripts.cpp rename : src/scripts/world/boss_emeriss.cpp => src/server/scripts/world/boss_emeriss.cpp rename : src/scripts/world/boss_lethon.cpp => src/server/scripts/world/boss_lethon.cpp rename : src/scripts/world/boss_taerar.cpp => src/server/scripts/world/boss_taerar.cpp rename : src/scripts/world/boss_ysondre.cpp => src/server/scripts/world/boss_ysondre.cpp rename : src/scripts/world/go_scripts.cpp => src/server/scripts/world/go_scripts.cpp rename : src/scripts/world/guards.cpp => src/server/scripts/world/guards.cpp rename : src/scripts/world/item_scripts.cpp => src/server/scripts/world/item_scripts.cpp rename : src/scripts/world/mob_generic_creature.cpp => src/server/scripts/world/mob_generic_creature.cpp rename : src/scripts/world/npc_innkeeper.cpp => src/server/scripts/world/npc_innkeeper.cpp rename : src/scripts/world/npc_professions.cpp => src/server/scripts/world/npc_professions.cpp rename : src/scripts/world/npc_taxi.cpp => src/server/scripts/world/npc_taxi.cpp rename : src/scripts/world/npcs_special.cpp => src/server/scripts/world/npcs_special.cpp rename : src/shared/Auth/AuthCrypt.cpp => src/server/shared/Auth/AuthCrypt.cpp rename : src/shared/Auth/AuthCrypt.h => src/server/shared/Auth/AuthCrypt.h rename : src/shared/Auth/BigNumber.cpp => src/server/shared/Auth/BigNumber.cpp rename : src/shared/Auth/BigNumber.h => src/server/shared/Auth/BigNumber.h rename : src/shared/Auth/CMakeLists.txt => src/server/shared/Auth/CMakeLists.txt rename : src/shared/Auth/Hmac.cpp => src/server/shared/Auth/Hmac.cpp rename : src/shared/Auth/Hmac.h => src/server/shared/Auth/Hmac.h rename : src/shared/Auth/SARC4.cpp => src/server/shared/Auth/SARC4.cpp rename : src/shared/Auth/SARC4.h => src/server/shared/Auth/SARC4.h rename : src/shared/Auth/Sha1.cpp => src/server/shared/Auth/Sha1.cpp rename : src/shared/Auth/Sha1.h => src/server/shared/Auth/Sha1.h rename : src/shared/Auth/md5.c => src/server/shared/Auth/md5.c rename : src/shared/Auth/md5.h => src/server/shared/Auth/md5.h rename : src/shared/ByteBuffer.h => src/server/shared/ByteBuffer.h rename : src/shared/CMakeLists.txt => src/server/shared/CMakeLists.txt rename : src/shared/Common.cpp => src/server/shared/Common.cpp rename : src/shared/Common.h => src/server/shared/Common.h rename : src/shared/Config/CMakeLists.txt => src/server/shared/Config/CMakeLists.txt rename : src/shared/Config/Config.cpp => src/server/shared/Config/Config.cpp rename : src/shared/Config/Config.h => src/server/shared/Config/Config.h rename : src/shared/Config/ConfigEnv.h => src/server/shared/Config/ConfigEnv.h rename : src/shared/Config/ConfigLibrary.vcproj => src/server/shared/Config/ConfigLibrary.vcproj rename : src/shared/Config/dotconfpp/dotconfpp.cpp => src/server/shared/Config/dotconfpp/dotconfpp.cpp rename : src/shared/Config/dotconfpp/dotconfpp.h => src/server/shared/Config/dotconfpp/dotconfpp.h rename : src/shared/Config/dotconfpp/mempool.cpp => src/server/shared/Config/dotconfpp/mempool.cpp rename : src/shared/Config/dotconfpp/mempool.h => src/server/shared/Config/dotconfpp/mempool.h rename : src/shared/Database/CMakeLists.txt => src/server/shared/Database/CMakeLists.txt rename : src/shared/Database/DBCFileLoader.cpp => src/server/shared/Database/DBCFileLoader.cpp rename : src/shared/Database/DBCFileLoader.h => src/server/shared/Database/DBCFileLoader.h rename : src/shared/Database/DBCStore.h => src/server/shared/Database/DBCStore.h rename : src/shared/Database/Database.cpp => src/server/shared/Database/Database.cpp rename : src/shared/Database/Database.h => src/server/shared/Database/Database.h rename : src/shared/Database/DatabaseEnv.h => src/server/shared/Database/DatabaseEnv.h rename : src/shared/Database/DatabaseImpl.h => src/server/shared/Database/DatabaseImpl.h rename : src/shared/Database/Field.cpp => src/server/shared/Database/Field.cpp rename : src/shared/Database/Field.h => src/server/shared/Database/Field.h rename : src/shared/Database/QueryResult.cpp => src/server/shared/Database/QueryResult.cpp rename : src/shared/Database/QueryResult.h => src/server/shared/Database/QueryResult.h rename : src/shared/Database/SQLStorage.cpp => src/server/shared/Database/SQLStorage.cpp rename : src/shared/Database/SQLStorage.h => src/server/shared/Database/SQLStorage.h rename : src/shared/Database/SQLStorageImpl.h => src/server/shared/Database/SQLStorageImpl.h rename : src/shared/Database/SqlDelayThread.cpp => src/server/shared/Database/SqlDelayThread.cpp rename : src/shared/Database/SqlDelayThread.h => src/server/shared/Database/SqlDelayThread.h rename : src/shared/Database/SqlOperations.cpp => src/server/shared/Database/SqlOperations.cpp rename : src/shared/Database/SqlOperations.h => src/server/shared/Database/SqlOperations.h rename : src/shared/DelayExecutor.cpp => src/server/shared/DelayExecutor.cpp rename : src/shared/DelayExecutor.h => src/server/shared/DelayExecutor.h rename : src/shared/Errors.h => src/server/shared/Errors.h rename : src/shared/LockedQueue.h => src/server/shared/LockedQueue.h rename : src/shared/Log.cpp => src/server/shared/Log.cpp rename : src/shared/Log.h => src/server/shared/Log.h rename : src/shared/MemoryLeaks.cpp => src/server/shared/MemoryLeaks.cpp rename : src/shared/MemoryLeaks.h => src/server/shared/MemoryLeaks.h rename : src/shared/PacketLog.cpp => src/server/shared/PacketLog.cpp rename : src/shared/PacketLog.h => src/server/shared/PacketLog.h rename : src/shared/ProgressBar.cpp => src/server/shared/ProgressBar.cpp rename : src/shared/ProgressBar.h => src/server/shared/ProgressBar.h rename : src/shared/ServiceWin32.cpp => src/server/shared/ServiceWin32.cpp rename : src/shared/ServiceWin32.h => src/server/shared/ServiceWin32.h rename : src/shared/SignalHandler.h => src/server/shared/SignalHandler.h rename : src/shared/SystemConfig.h => src/server/shared/SystemConfig.h rename : src/shared/Threading.cpp => src/server/shared/Threading.cpp rename : src/shared/Threading.h => src/server/shared/Threading.h rename : src/shared/Timer.h => src/server/shared/Timer.h rename : src/shared/Util.cpp => src/server/shared/Util.cpp rename : src/shared/Util.h => src/server/shared/Util.h rename : src/shared/WheatyExceptionReport.cpp => src/server/shared/WheatyExceptionReport.cpp rename : src/shared/WheatyExceptionReport.h => src/server/shared/WheatyExceptionReport.h rename : src/shared/WorldPacket.h => src/server/shared/WorldPacket.h rename : src/shared/vmap/BIH.cpp => src/server/shared/vmap/BIH.cpp rename : src/shared/vmap/BIH.h => src/server/shared/vmap/BIH.h rename : src/shared/vmap/CMakeLists.txt => src/server/shared/vmap/CMakeLists.txt rename : src/shared/vmap/IVMapManager.h => src/server/shared/vmap/IVMapManager.h rename : src/shared/vmap/MapTree.cpp => src/server/shared/vmap/MapTree.cpp rename : src/shared/vmap/MapTree.h => src/server/shared/vmap/MapTree.h rename : src/shared/vmap/ModelInstance.cpp => src/server/shared/vmap/ModelInstance.cpp rename : src/shared/vmap/ModelInstance.h => src/server/shared/vmap/ModelInstance.h rename : src/shared/vmap/TileAssembler.cpp => src/server/shared/vmap/TileAssembler.cpp rename : src/shared/vmap/TileAssembler.h => src/server/shared/vmap/TileAssembler.h rename : src/shared/vmap/VMapDefinitions.h => src/server/shared/vmap/VMapDefinitions.h rename : src/shared/vmap/VMapFactory.cpp => src/server/shared/vmap/VMapFactory.cpp rename : src/shared/vmap/VMapFactory.h => src/server/shared/vmap/VMapFactory.h rename : src/shared/vmap/VMapManager2.cpp => src/server/shared/vmap/VMapManager2.cpp rename : src/shared/vmap/VMapManager2.h => src/server/shared/vmap/VMapManager2.h rename : src/shared/vmap/VMapTools.h => src/server/shared/vmap/VMapTools.h rename : src/shared/vmap/WorldModel.cpp => src/server/shared/vmap/WorldModel.cpp rename : src/shared/vmap/WorldModel.h => src/server/shared/vmap/WorldModel.h rename : src/trinitycore/CMakeLists.txt => src/server/trinitycore/CMakeLists.txt rename : src/trinitycore/CliRunnable.cpp => src/server/trinitycore/CliRunnable.cpp rename : src/trinitycore/CliRunnable.h => src/server/trinitycore/CliRunnable.h rename : src/trinitycore/Main.cpp => src/server/trinitycore/Main.cpp rename : src/trinitycore/Master.cpp => src/server/trinitycore/Master.cpp rename : src/trinitycore/Master.h => src/server/trinitycore/Master.h rename : src/trinitycore/RASocket.cpp => src/server/trinitycore/RASocket.cpp rename : src/trinitycore/RASocket.h => src/server/trinitycore/RASocket.h rename : src/trinitycore/TrinityCore.ico => src/server/trinitycore/TrinityCore.ico rename : src/trinitycore/TrinityCore.rc => src/server/trinitycore/TrinityCore.rc rename : src/trinitycore/WorldRunnable.cpp => src/server/trinitycore/WorldRunnable.cpp rename : src/trinitycore/WorldRunnable.h => src/server/trinitycore/WorldRunnable.h rename : src/trinitycore/resource.h => src/server/trinitycore/resource.h rename : src/trinitycore/trinitycore.conf.dist => src/server/trinitycore/trinitycore.conf.dist rename : src/trinityrealm/AuthCodes.cpp => src/server/trinityrealm/AuthCodes.cpp rename : src/trinityrealm/AuthCodes.h => src/server/trinityrealm/AuthCodes.h rename : src/trinityrealm/AuthSocket.cpp => src/server/trinityrealm/AuthSocket.cpp rename : src/trinityrealm/AuthSocket.h => src/server/trinityrealm/AuthSocket.h rename : src/trinityrealm/CMakeLists.txt => src/server/trinityrealm/CMakeLists.txt rename : src/trinityrealm/Main.cpp => src/server/trinityrealm/Main.cpp rename : src/trinityrealm/RealmAcceptor.h => src/server/trinityrealm/RealmAcceptor.h rename : src/trinityrealm/RealmList.cpp => src/server/trinityrealm/RealmList.cpp rename : src/trinityrealm/RealmList.h => src/server/trinityrealm/RealmList.h rename : src/trinityrealm/RealmSocket.cpp => src/server/trinityrealm/RealmSocket.cpp rename : src/trinityrealm/RealmSocket.h => src/server/trinityrealm/RealmSocket.h rename : src/trinityrealm/TrinityRealm.ico => src/server/trinityrealm/TrinityRealm.ico rename : src/trinityrealm/TrinityRealm.rc => src/server/trinityrealm/TrinityRealm.rc rename : src/trinityrealm/resource.h => src/server/trinityrealm/resource.h rename : src/trinityrealm/trinityrealm.conf.dist => src/server/trinityrealm/trinityrealm.conf.dist
This commit is contained in:
@@ -0,0 +1,81 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
|
||||
*
|
||||
* Copyright (C) 2008-2010 Trinity <http://www.trinitycore.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; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include "AuthCrypt.h"
|
||||
#include "Hmac.h"
|
||||
#include "Log.h"
|
||||
#include "BigNumber.h"
|
||||
|
||||
AuthCrypt::AuthCrypt() : _clientDecrypt(SHA_DIGEST_LENGTH), _serverEncrypt(SHA_DIGEST_LENGTH)
|
||||
{
|
||||
_initialized = false;
|
||||
}
|
||||
|
||||
AuthCrypt::~AuthCrypt()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void AuthCrypt::Init(BigNumber *K)
|
||||
{
|
||||
uint8 ServerEncryptionKey[SEED_KEY_SIZE] = { 0xCC, 0x98, 0xAE, 0x04, 0xE8, 0x97, 0xEA, 0xCA, 0x12, 0xDD, 0xC0, 0x93, 0x42, 0x91, 0x53, 0x57 };
|
||||
HmacHash serverEncryptHmac(SEED_KEY_SIZE, (uint8*)ServerEncryptionKey);
|
||||
uint8 *encryptHash = serverEncryptHmac.ComputeHash(K);
|
||||
|
||||
uint8 ServerDecryptionKey[SEED_KEY_SIZE] = { 0xC2, 0xB3, 0x72, 0x3C, 0xC6, 0xAE, 0xD9, 0xB5, 0x34, 0x3C, 0x53, 0xEE, 0x2F, 0x43, 0x67, 0xCE };
|
||||
HmacHash clientDecryptHmac(SEED_KEY_SIZE, (uint8*)ServerDecryptionKey);
|
||||
uint8 *decryptHash = clientDecryptHmac.ComputeHash(K);
|
||||
|
||||
//SARC4 _serverDecrypt(encryptHash);
|
||||
_clientDecrypt.Init(decryptHash);
|
||||
_serverEncrypt.Init(encryptHash);
|
||||
//SARC4 _clientEncrypt(decryptHash);
|
||||
|
||||
uint8 syncBuf[1024];
|
||||
|
||||
memset(syncBuf, 0, 1024);
|
||||
|
||||
_serverEncrypt.UpdateData(1024, syncBuf);
|
||||
//_clientEncrypt.UpdateData(1024, syncBuf);
|
||||
|
||||
memset(syncBuf, 0, 1024);
|
||||
|
||||
//_serverDecrypt.UpdateData(1024, syncBuf);
|
||||
_clientDecrypt.UpdateData(1024, syncBuf);
|
||||
|
||||
_initialized = true;
|
||||
}
|
||||
|
||||
void AuthCrypt::DecryptRecv(uint8 *data, size_t len)
|
||||
{
|
||||
if (!_initialized)
|
||||
return;
|
||||
|
||||
_clientDecrypt.UpdateData(len, data);
|
||||
}
|
||||
|
||||
void AuthCrypt::EncryptSend(uint8 *data, size_t len)
|
||||
{
|
||||
if (!_initialized)
|
||||
return;
|
||||
|
||||
_serverEncrypt.UpdateData(len, data);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
|
||||
*
|
||||
* Copyright (C) 2008-2010 Trinity <http://www.trinitycore.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; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef _AUTHCRYPT_H
|
||||
#define _AUTHCRYPT_H
|
||||
|
||||
#include <Common.h>
|
||||
#include "SARC4.h"
|
||||
|
||||
class BigNumber;
|
||||
|
||||
class AuthCrypt
|
||||
{
|
||||
public:
|
||||
AuthCrypt();
|
||||
~AuthCrypt();
|
||||
|
||||
void Init(BigNumber *K);
|
||||
void DecryptRecv(uint8 *, size_t);
|
||||
void EncryptSend(uint8 *, size_t);
|
||||
|
||||
bool IsInitialized() { return _initialized; }
|
||||
|
||||
private:
|
||||
SARC4 _clientDecrypt;
|
||||
SARC4 _serverEncrypt;
|
||||
bool _initialized;
|
||||
};
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,201 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
|
||||
*
|
||||
* Copyright (C) 2008-2010 Trinity <http://www.trinitycore.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; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include "Auth/BigNumber.h"
|
||||
#include <openssl/bn.h>
|
||||
#include <algorithm>
|
||||
|
||||
BigNumber::BigNumber()
|
||||
{
|
||||
_bn = BN_new();
|
||||
_array = NULL;
|
||||
}
|
||||
|
||||
BigNumber::BigNumber(const BigNumber &bn)
|
||||
{
|
||||
_bn = BN_dup(bn._bn);
|
||||
_array = NULL;
|
||||
}
|
||||
|
||||
BigNumber::BigNumber(uint32 val)
|
||||
{
|
||||
_bn = BN_new();
|
||||
BN_set_word(_bn, val);
|
||||
_array = NULL;
|
||||
}
|
||||
|
||||
BigNumber::~BigNumber()
|
||||
{
|
||||
BN_free(_bn);
|
||||
if(_array) delete[] _array;
|
||||
}
|
||||
|
||||
void BigNumber::SetDword(uint32 val)
|
||||
{
|
||||
BN_set_word(_bn, val);
|
||||
}
|
||||
|
||||
void BigNumber::SetQword(uint64 val)
|
||||
{
|
||||
BN_add_word(_bn, (uint32)(val >> 32));
|
||||
BN_lshift(_bn, _bn, 32);
|
||||
BN_add_word(_bn, (uint32)(val & 0xFFFFFFFF));
|
||||
}
|
||||
|
||||
void BigNumber::SetBinary(const uint8 *bytes, int len)
|
||||
{
|
||||
uint8 t[1000];
|
||||
for (int i = 0; i < len; i++) t[i] = bytes[len - 1 - i];
|
||||
BN_bin2bn(t, len, _bn);
|
||||
}
|
||||
|
||||
void BigNumber::SetHexStr(const char *str)
|
||||
{
|
||||
BN_hex2bn(&_bn, str);
|
||||
}
|
||||
|
||||
void BigNumber::SetRand(int numbits)
|
||||
{
|
||||
BN_rand(_bn, numbits, 0, 1);
|
||||
}
|
||||
|
||||
BigNumber BigNumber::operator=(const BigNumber &bn)
|
||||
{
|
||||
BN_copy(_bn, bn._bn);
|
||||
return *this;
|
||||
}
|
||||
|
||||
BigNumber BigNumber::operator+=(const BigNumber &bn)
|
||||
{
|
||||
BN_add(_bn, _bn, bn._bn);
|
||||
return *this;
|
||||
}
|
||||
|
||||
BigNumber BigNumber::operator-=(const BigNumber &bn)
|
||||
{
|
||||
BN_sub(_bn, _bn, bn._bn);
|
||||
return *this;
|
||||
}
|
||||
|
||||
BigNumber BigNumber::operator*=(const BigNumber &bn)
|
||||
{
|
||||
BN_CTX *bnctx;
|
||||
|
||||
bnctx = BN_CTX_new();
|
||||
BN_mul(_bn, _bn, bn._bn, bnctx);
|
||||
BN_CTX_free(bnctx);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
BigNumber BigNumber::operator/=(const BigNumber &bn)
|
||||
{
|
||||
BN_CTX *bnctx;
|
||||
|
||||
bnctx = BN_CTX_new();
|
||||
BN_div(_bn, NULL, _bn, bn._bn, bnctx);
|
||||
BN_CTX_free(bnctx);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
BigNumber BigNumber::operator%=(const BigNumber &bn)
|
||||
{
|
||||
BN_CTX *bnctx;
|
||||
|
||||
bnctx = BN_CTX_new();
|
||||
BN_mod(_bn, _bn, bn._bn, bnctx);
|
||||
BN_CTX_free(bnctx);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
BigNumber BigNumber::Exp(const BigNumber &bn)
|
||||
{
|
||||
BigNumber ret;
|
||||
BN_CTX *bnctx;
|
||||
|
||||
bnctx = BN_CTX_new();
|
||||
BN_exp(ret._bn, _bn, bn._bn, bnctx);
|
||||
BN_CTX_free(bnctx);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
BigNumber BigNumber::ModExp(const BigNumber &bn1, const BigNumber &bn2)
|
||||
{
|
||||
BigNumber ret;
|
||||
BN_CTX *bnctx;
|
||||
|
||||
bnctx = BN_CTX_new();
|
||||
BN_mod_exp(ret._bn, _bn, bn1._bn, bn2._bn, bnctx);
|
||||
BN_CTX_free(bnctx);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int BigNumber::GetNumBytes(void)
|
||||
{
|
||||
return BN_num_bytes(_bn);
|
||||
}
|
||||
|
||||
uint32 BigNumber::AsDword()
|
||||
{
|
||||
return (uint32)BN_get_word(_bn);
|
||||
}
|
||||
|
||||
bool BigNumber::isZero() const
|
||||
{
|
||||
return BN_is_zero(_bn)!=0;
|
||||
}
|
||||
|
||||
uint8 *BigNumber::AsByteArray(int minSize, bool reverse)
|
||||
{
|
||||
int length = (minSize >= GetNumBytes()) ? minSize : GetNumBytes();
|
||||
|
||||
if (_array)
|
||||
{
|
||||
delete[] _array;
|
||||
_array = NULL;
|
||||
}
|
||||
_array = new uint8[length];
|
||||
|
||||
// If we need more bytes than length of BigNumber set the rest to 0
|
||||
if (length > GetNumBytes())
|
||||
memset((void*)_array, 0, length);
|
||||
|
||||
BN_bn2bin(_bn, (unsigned char *)_array);
|
||||
|
||||
if (reverse)
|
||||
std::reverse(_array, _array + length);
|
||||
|
||||
return _array;
|
||||
}
|
||||
|
||||
const char *BigNumber::AsHexStr()
|
||||
{
|
||||
return BN_bn2hex(_bn);
|
||||
}
|
||||
|
||||
const char *BigNumber::AsDecStr()
|
||||
{
|
||||
return BN_bn2dec(_bn);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,96 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
|
||||
*
|
||||
* Copyright (C) 2008-2010 Trinity <http://www.trinitycore.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; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef _AUTH_BIGNUMBER_H
|
||||
#define _AUTH_BIGNUMBER_H
|
||||
|
||||
#include "Common.h"
|
||||
|
||||
struct bignum_st;
|
||||
|
||||
class BigNumber
|
||||
{
|
||||
public:
|
||||
BigNumber();
|
||||
BigNumber(const BigNumber &bn);
|
||||
BigNumber(uint32);
|
||||
~BigNumber();
|
||||
|
||||
void SetDword(uint32);
|
||||
void SetQword(uint64);
|
||||
void SetBinary(const uint8 *bytes, int len);
|
||||
void SetHexStr(const char *str);
|
||||
|
||||
void SetRand(int numbits);
|
||||
|
||||
BigNumber operator=(const BigNumber &bn);
|
||||
|
||||
BigNumber operator+=(const BigNumber &bn);
|
||||
BigNumber operator+(const BigNumber &bn)
|
||||
{
|
||||
BigNumber t(*this);
|
||||
return t += bn;
|
||||
}
|
||||
BigNumber operator-=(const BigNumber &bn);
|
||||
BigNumber operator-(const BigNumber &bn)
|
||||
{
|
||||
BigNumber t(*this);
|
||||
return t -= bn;
|
||||
}
|
||||
BigNumber operator*=(const BigNumber &bn);
|
||||
BigNumber operator*(const BigNumber &bn)
|
||||
{
|
||||
BigNumber t(*this);
|
||||
return t *= bn;
|
||||
}
|
||||
BigNumber operator/=(const BigNumber &bn);
|
||||
BigNumber operator/(const BigNumber &bn)
|
||||
{
|
||||
BigNumber t(*this);
|
||||
return t /= bn;
|
||||
}
|
||||
BigNumber operator%=(const BigNumber &bn);
|
||||
BigNumber operator%(const BigNumber &bn)
|
||||
{
|
||||
BigNumber t(*this);
|
||||
return t %= bn;
|
||||
}
|
||||
|
||||
bool isZero() const;
|
||||
|
||||
BigNumber ModExp(const BigNumber &bn1, const BigNumber &bn2);
|
||||
BigNumber Exp(const BigNumber &);
|
||||
|
||||
int GetNumBytes(void);
|
||||
|
||||
struct bignum_st *BN() { return _bn; }
|
||||
|
||||
uint32 AsDword();
|
||||
uint8* AsByteArray(int minSize = 0, bool reverse = true);
|
||||
|
||||
const char *AsHexStr();
|
||||
const char *AsDecStr();
|
||||
|
||||
private:
|
||||
struct bignum_st *_bn;
|
||||
uint8 *_array;
|
||||
};
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
|
||||
########### next target ###############
|
||||
|
||||
SET(trinityauth_STAT_SRCS
|
||||
AuthCrypt.cpp
|
||||
AuthCrypt.h
|
||||
BigNumber.cpp
|
||||
BigNumber.h
|
||||
Hmac.cpp
|
||||
Hmac.h
|
||||
Sha1.cpp
|
||||
Sha1.h
|
||||
md5.c
|
||||
md5.h
|
||||
SARC4.cpp
|
||||
SARC4.h
|
||||
)
|
||||
|
||||
include_directories(
|
||||
${ACE_INCLUDE_DIR}
|
||||
${CMAKE_BINARY_DIR}
|
||||
${CMAKE_SOURCE_DIR}/src/shared
|
||||
${CMAKE_SOURCE_DIR}/src/framework
|
||||
${MYSQL_INCLUDE_DIR}
|
||||
)
|
||||
|
||||
add_library(trinityauth STATIC ${trinityauth_STAT_SRCS})
|
||||
@@ -0,0 +1,62 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
|
||||
*
|
||||
* Copyright (C) 2008-2010 Trinity <http://www.trinitycore.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; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include "Auth/Hmac.h"
|
||||
#include "BigNumber.h"
|
||||
|
||||
HmacHash::HmacHash(uint32 len, uint8 *seed)
|
||||
{
|
||||
HMAC_CTX_init(&m_ctx);
|
||||
HMAC_Init_ex(&m_ctx, seed, len, EVP_sha1(), NULL);
|
||||
}
|
||||
|
||||
HmacHash::~HmacHash()
|
||||
{
|
||||
HMAC_CTX_cleanup(&m_ctx);
|
||||
}
|
||||
|
||||
void HmacHash::UpdateBigNumber(BigNumber *bn)
|
||||
{
|
||||
UpdateData(bn->AsByteArray(), bn->GetNumBytes());
|
||||
}
|
||||
|
||||
void HmacHash::UpdateData(const uint8 *data, int length)
|
||||
{
|
||||
HMAC_Update(&m_ctx, data, length);
|
||||
}
|
||||
|
||||
void HmacHash::UpdateData(const std::string &str)
|
||||
{
|
||||
UpdateData((uint8 const*)str.c_str(), str.length());
|
||||
}
|
||||
|
||||
void HmacHash::Finalize()
|
||||
{
|
||||
uint32 length = 0;
|
||||
HMAC_Final(&m_ctx, (uint8*)m_digest, &length);
|
||||
ASSERT(length == SHA_DIGEST_LENGTH)
|
||||
}
|
||||
|
||||
uint8 *HmacHash::ComputeHash(BigNumber *bn)
|
||||
{
|
||||
HMAC_Update(&m_ctx, bn->AsByteArray(), bn->GetNumBytes());
|
||||
Finalize();
|
||||
return (uint8*)m_digest;
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
|
||||
*
|
||||
* Copyright (C) 2008-2010 Trinity <http://www.trinitycore.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; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef _AUTH_HMAC_H
|
||||
#define _AUTH_HMAC_H
|
||||
|
||||
#include "Common.h"
|
||||
#include <openssl/hmac.h>
|
||||
#include <openssl/sha.h>
|
||||
|
||||
class BigNumber;
|
||||
|
||||
#define SEED_KEY_SIZE 16
|
||||
|
||||
class HmacHash
|
||||
{
|
||||
public:
|
||||
HmacHash(uint32 len, uint8 *seed);
|
||||
~HmacHash();
|
||||
void UpdateBigNumber(BigNumber *bn);
|
||||
void UpdateData(const uint8 *data, int length);
|
||||
void UpdateData(const std::string &str);
|
||||
void Finalize();
|
||||
uint8 *ComputeHash(BigNumber *bn);
|
||||
uint8 *GetDigest() { return (uint8*)m_digest; }
|
||||
int GetLength() { return SHA_DIGEST_LENGTH; }
|
||||
private:
|
||||
HMAC_CTX m_ctx;
|
||||
uint8 m_digest[SHA_DIGEST_LENGTH];
|
||||
};
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include "Auth/SARC4.h"
|
||||
#include <openssl/sha.h>
|
||||
|
||||
SARC4::SARC4(uint8 len)
|
||||
{
|
||||
EVP_CIPHER_CTX_init(&m_ctx);
|
||||
EVP_EncryptInit_ex(&m_ctx, EVP_rc4(), NULL, NULL, NULL);
|
||||
EVP_CIPHER_CTX_set_key_length(&m_ctx, len);
|
||||
}
|
||||
|
||||
SARC4::SARC4(uint8 *seed, uint8 len)
|
||||
{
|
||||
EVP_CIPHER_CTX_init(&m_ctx);
|
||||
EVP_EncryptInit_ex(&m_ctx, EVP_rc4(), NULL, NULL, NULL);
|
||||
EVP_CIPHER_CTX_set_key_length(&m_ctx, len);
|
||||
EVP_EncryptInit_ex(&m_ctx, NULL, NULL, seed, NULL);
|
||||
}
|
||||
|
||||
SARC4::~SARC4()
|
||||
{
|
||||
EVP_CIPHER_CTX_cleanup(&m_ctx);
|
||||
}
|
||||
|
||||
void SARC4::Init(uint8 *seed)
|
||||
{
|
||||
EVP_EncryptInit_ex(&m_ctx, NULL, NULL, seed, NULL);
|
||||
}
|
||||
|
||||
void SARC4::UpdateData(int len, uint8 *data)
|
||||
{
|
||||
int outlen = 0;
|
||||
EVP_EncryptUpdate(&m_ctx, data, &outlen, data, len);
|
||||
EVP_EncryptFinal_ex(&m_ctx, data, &outlen);
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef _AUTH_SARC4_H
|
||||
#define _AUTH_SARC4_H
|
||||
|
||||
#include "Common.h"
|
||||
#include <openssl/evp.h>
|
||||
|
||||
class SARC4
|
||||
{
|
||||
public:
|
||||
SARC4(uint8 len);
|
||||
SARC4(uint8 *seed, uint8 len);
|
||||
~SARC4();
|
||||
void Init(uint8 *seed);
|
||||
void UpdateData(int len, uint8 *data);
|
||||
private:
|
||||
EVP_CIPHER_CTX m_ctx;
|
||||
};
|
||||
#endif
|
||||
@@ -0,0 +1,69 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
|
||||
*
|
||||
* Copyright (C) 2008-2010 Trinity <http://www.trinitycore.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; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include "Auth/Sha1.h"
|
||||
#include "Auth/BigNumber.h"
|
||||
#include <stdarg.h>
|
||||
|
||||
Sha1Hash::Sha1Hash()
|
||||
{
|
||||
SHA1_Init(&mC);
|
||||
}
|
||||
|
||||
Sha1Hash::~Sha1Hash()
|
||||
{
|
||||
SHA1_Init(&mC);
|
||||
}
|
||||
|
||||
void Sha1Hash::UpdateData(const uint8 *dta, int len)
|
||||
{
|
||||
SHA1_Update(&mC, dta, len);
|
||||
}
|
||||
|
||||
void Sha1Hash::UpdateData(const std::string &str)
|
||||
{
|
||||
UpdateData((uint8 const*)str.c_str(), str.length());
|
||||
}
|
||||
|
||||
void Sha1Hash::UpdateBigNumbers(BigNumber *bn0, ...)
|
||||
{
|
||||
va_list v;
|
||||
BigNumber *bn;
|
||||
|
||||
va_start(v, bn0);
|
||||
bn = bn0;
|
||||
while (bn)
|
||||
{
|
||||
UpdateData(bn->AsByteArray(), bn->GetNumBytes());
|
||||
bn = va_arg(v, BigNumber *);
|
||||
}
|
||||
va_end(v);
|
||||
}
|
||||
|
||||
void Sha1Hash::Initialize()
|
||||
{
|
||||
SHA1_Init(&mC);
|
||||
}
|
||||
|
||||
void Sha1Hash::Finalize(void)
|
||||
{
|
||||
SHA1_Final(mDigest, &mC);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,53 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
|
||||
*
|
||||
* Copyright (C) 2008-2010 Trinity <http://www.trinitycore.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; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef _AUTH_SHA1_H
|
||||
#define _AUTH_SHA1_H
|
||||
|
||||
#include "Common.h"
|
||||
#include <openssl/sha.h>
|
||||
#include <openssl/crypto.h>
|
||||
|
||||
class BigNumber;
|
||||
|
||||
class Sha1Hash
|
||||
{
|
||||
public:
|
||||
Sha1Hash();
|
||||
~Sha1Hash();
|
||||
|
||||
void UpdateFinalizeBigNumbers(BigNumber *bn0, ...);
|
||||
void UpdateBigNumbers(BigNumber *bn0, ...);
|
||||
|
||||
void UpdateData(const uint8 *dta, int len);
|
||||
void UpdateData(const std::string &str);
|
||||
|
||||
void Initialize();
|
||||
void Finalize();
|
||||
|
||||
uint8 *GetDigest(void) { return mDigest; };
|
||||
int GetLength(void) { return SHA_DIGEST_LENGTH; };
|
||||
|
||||
private:
|
||||
SHA_CTX mC;
|
||||
uint8 mDigest[SHA_DIGEST_LENGTH];
|
||||
};
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,385 @@
|
||||
/*
|
||||
Copyright (C) 1999, 2000, 2002 Aladdin Enterprises. All rights reserved.
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
|
||||
L. Peter Deutsch
|
||||
[email protected]
|
||||
|
||||
*/
|
||||
/* $Id: md5.c,v 1.6 2002/04/13 19:20:28 lpd Exp $ */
|
||||
/*
|
||||
Independent implementation of MD5 (RFC 1321).
|
||||
|
||||
This code implements the MD5 Algorithm defined in RFC 1321, whose
|
||||
text is available at
|
||||
http://www.ietf.org/rfc/rfc1321.txt
|
||||
The code is derived from the text of the RFC, including the test suite
|
||||
(section A.5) but excluding the rest of Appendix A. It does not include
|
||||
any code or documentation that is identified in the RFC as being
|
||||
copyrighted.
|
||||
|
||||
The original and principal author of md5.c is L. Peter Deutsch
|
||||
<[email protected]>. Other authors are noted in the change history
|
||||
that follows (in reverse chronological order):
|
||||
|
||||
2002-04-13 lpd Clarified derivation from RFC 1321; now handles byte order
|
||||
either statically or dynamically; added missing #include <string.h>
|
||||
in library.
|
||||
2002-03-11 lpd Corrected argument list for main(), and added int return
|
||||
type, in test program and T value program.
|
||||
2002-02-21 lpd Added missing #include <stdio.h> in test program.
|
||||
2000-07-03 lpd Patched to eliminate warnings about "constant is
|
||||
unsigned in ANSI C, signed in traditional"; made test program
|
||||
self-checking.
|
||||
1999-11-04 lpd Edited comments slightly for automatic TOC extraction.
|
||||
1999-10-18 lpd Fixed typo in header comment (ansi2knr rather than md5).
|
||||
1999-05-03 lpd Original version.
|
||||
*/
|
||||
|
||||
#include "md5.h"
|
||||
#include <string.h>
|
||||
|
||||
#undef BYTE_ORDER /* 1 = big-endian, -1 = little-endian, 0 = unknown */
|
||||
#ifdef ARCH_IS_BIG_ENDIAN
|
||||
# define BYTE_ORDER (ARCH_IS_BIG_ENDIAN ? 1 : -1)
|
||||
#else
|
||||
# define BYTE_ORDER 0
|
||||
#endif
|
||||
|
||||
#define T_MASK ((md5_word_t)~0)
|
||||
#define T1 /* 0xd76aa478 */ (T_MASK ^ 0x28955b87)
|
||||
#define T2 /* 0xe8c7b756 */ (T_MASK ^ 0x173848a9)
|
||||
#define T3 0x242070db
|
||||
#define T4 /* 0xc1bdceee */ (T_MASK ^ 0x3e423111)
|
||||
#define T5 /* 0xf57c0faf */ (T_MASK ^ 0x0a83f050)
|
||||
#define T6 0x4787c62a
|
||||
#define T7 /* 0xa8304613 */ (T_MASK ^ 0x57cfb9ec)
|
||||
#define T8 /* 0xfd469501 */ (T_MASK ^ 0x02b96afe)
|
||||
#define T9 0x698098d8
|
||||
#define T10 /* 0x8b44f7af */ (T_MASK ^ 0x74bb0850)
|
||||
#define T11 /* 0xffff5bb1 */ (T_MASK ^ 0x0000a44e)
|
||||
#define T12 /* 0x895cd7be */ (T_MASK ^ 0x76a32841)
|
||||
#define T13 0x6b901122
|
||||
#define T14 /* 0xfd987193 */ (T_MASK ^ 0x02678e6c)
|
||||
#define T15 /* 0xa679438e */ (T_MASK ^ 0x5986bc71)
|
||||
#define T16 0x49b40821
|
||||
#define T17 /* 0xf61e2562 */ (T_MASK ^ 0x09e1da9d)
|
||||
#define T18 /* 0xc040b340 */ (T_MASK ^ 0x3fbf4cbf)
|
||||
#define T19 0x265e5a51
|
||||
#define T20 /* 0xe9b6c7aa */ (T_MASK ^ 0x16493855)
|
||||
#define T21 /* 0xd62f105d */ (T_MASK ^ 0x29d0efa2)
|
||||
#define T22 0x02441453
|
||||
#define T23 /* 0xd8a1e681 */ (T_MASK ^ 0x275e197e)
|
||||
#define T24 /* 0xe7d3fbc8 */ (T_MASK ^ 0x182c0437)
|
||||
#define T25 0x21e1cde6
|
||||
#define T26 /* 0xc33707d6 */ (T_MASK ^ 0x3cc8f829)
|
||||
#define T27 /* 0xf4d50d87 */ (T_MASK ^ 0x0b2af278)
|
||||
#define T28 0x455a14ed
|
||||
#define T29 /* 0xa9e3e905 */ (T_MASK ^ 0x561c16fa)
|
||||
#define T30 /* 0xfcefa3f8 */ (T_MASK ^ 0x03105c07)
|
||||
#define T31 0x676f02d9
|
||||
#define T32 /* 0x8d2a4c8a */ (T_MASK ^ 0x72d5b375)
|
||||
#define T33 /* 0xfffa3942 */ (T_MASK ^ 0x0005c6bd)
|
||||
#define T34 /* 0x8771f681 */ (T_MASK ^ 0x788e097e)
|
||||
#define T35 0x6d9d6122
|
||||
#define T36 /* 0xfde5380c */ (T_MASK ^ 0x021ac7f3)
|
||||
#define T37 /* 0xa4beea44 */ (T_MASK ^ 0x5b4115bb)
|
||||
#define T38 0x4bdecfa9
|
||||
#define T39 /* 0xf6bb4b60 */ (T_MASK ^ 0x0944b49f)
|
||||
#define T40 /* 0xbebfbc70 */ (T_MASK ^ 0x4140438f)
|
||||
#define T41 0x289b7ec6
|
||||
#define T42 /* 0xeaa127fa */ (T_MASK ^ 0x155ed805)
|
||||
#define T43 /* 0xd4ef3085 */ (T_MASK ^ 0x2b10cf7a)
|
||||
#define T44 0x04881d05
|
||||
#define T45 /* 0xd9d4d039 */ (T_MASK ^ 0x262b2fc6)
|
||||
#define T46 /* 0xe6db99e5 */ (T_MASK ^ 0x1924661a)
|
||||
#define T47 0x1fa27cf8
|
||||
#define T48 /* 0xc4ac5665 */ (T_MASK ^ 0x3b53a99a)
|
||||
#define T49 /* 0xf4292244 */ (T_MASK ^ 0x0bd6ddbb)
|
||||
#define T50 0x432aff97
|
||||
#define T51 /* 0xab9423a7 */ (T_MASK ^ 0x546bdc58)
|
||||
#define T52 /* 0xfc93a039 */ (T_MASK ^ 0x036c5fc6)
|
||||
#define T53 0x655b59c3
|
||||
#define T54 /* 0x8f0ccc92 */ (T_MASK ^ 0x70f3336d)
|
||||
#define T55 /* 0xffeff47d */ (T_MASK ^ 0x00100b82)
|
||||
#define T56 /* 0x85845dd1 */ (T_MASK ^ 0x7a7ba22e)
|
||||
#define T57 0x6fa87e4f
|
||||
#define T58 /* 0xfe2ce6e0 */ (T_MASK ^ 0x01d3191f)
|
||||
#define T59 /* 0xa3014314 */ (T_MASK ^ 0x5cfebceb)
|
||||
#define T60 0x4e0811a1
|
||||
#define T61 /* 0xf7537e82 */ (T_MASK ^ 0x08ac817d)
|
||||
#define T62 /* 0xbd3af235 */ (T_MASK ^ 0x42c50dca)
|
||||
#define T63 0x2ad7d2bb
|
||||
#define T64 /* 0xeb86d391 */ (T_MASK ^ 0x14792c6e)
|
||||
|
||||
static void
|
||||
md5_process(md5_state_t *pms, const md5_byte_t *data /*[64]*/)
|
||||
{
|
||||
md5_word_t
|
||||
a = pms->abcd[0], b = pms->abcd[1],
|
||||
c = pms->abcd[2], d = pms->abcd[3];
|
||||
md5_word_t t;
|
||||
#if BYTE_ORDER > 0
|
||||
/* Define storage only for big-endian CPUs. */
|
||||
md5_word_t X[16];
|
||||
#else
|
||||
/* Define storage for little-endian or both types of CPUs. */
|
||||
md5_word_t xbuf[16];
|
||||
const md5_word_t *X;
|
||||
#endif
|
||||
|
||||
{
|
||||
#if BYTE_ORDER == 0
|
||||
/*
|
||||
* Determine dynamically whether this is a big-endian or
|
||||
* little-endian machine, since we can use a more efficient
|
||||
* algorithm on the latter.
|
||||
*/
|
||||
static const int w = 1;
|
||||
|
||||
if (*((const md5_byte_t *)&w)) /* dynamic little-endian */
|
||||
#endif
|
||||
#if BYTE_ORDER <= 0 /* little-endian */
|
||||
{
|
||||
/*
|
||||
* On little-endian machines, we can process properly aligned
|
||||
* data without copying it.
|
||||
*/
|
||||
if (!((data - (const md5_byte_t *)0) & 3))
|
||||
{
|
||||
/* data are properly aligned */
|
||||
X = (const md5_word_t *)data;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* not aligned */
|
||||
memcpy(xbuf, data, 64);
|
||||
X = xbuf;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#if BYTE_ORDER == 0
|
||||
else /* dynamic big-endian */
|
||||
#endif
|
||||
#if BYTE_ORDER >= 0 /* big-endian */
|
||||
{
|
||||
/*
|
||||
* On big-endian machines, we must arrange the bytes in the
|
||||
* right order.
|
||||
*/
|
||||
const md5_byte_t *xp = data;
|
||||
int i;
|
||||
|
||||
# if BYTE_ORDER == 0
|
||||
X = xbuf; /* (dynamic only) */
|
||||
# else
|
||||
# define xbuf X /* (static only) */
|
||||
# endif
|
||||
for (i = 0; i < 16; ++i, xp += 4)
|
||||
xbuf[i] = xp[0] + (xp[1] << 8) + (xp[2] << 16) + (xp[3] << 24);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32 - (n))))
|
||||
|
||||
/* Round 1. */
|
||||
/* Let [abcd k s i] denote the operation
|
||||
a = b + ((a + F(b,c,d) + X[k] + T[i]) <<< s). */
|
||||
#define F(x, y, z) (((x) & (y)) | (~(x) & (z)))
|
||||
#define SET(a, b, c, d, k, s, Ti)\
|
||||
t = a + F(b,c,d) + X[k] + Ti;\
|
||||
a = ROTATE_LEFT(t, s) + b
|
||||
/* Do the following 16 operations. */
|
||||
SET(a, b, c, d, 0, 7, T1);
|
||||
SET(d, a, b, c, 1, 12, T2);
|
||||
SET(c, d, a, b, 2, 17, T3);
|
||||
SET(b, c, d, a, 3, 22, T4);
|
||||
SET(a, b, c, d, 4, 7, T5);
|
||||
SET(d, a, b, c, 5, 12, T6);
|
||||
SET(c, d, a, b, 6, 17, T7);
|
||||
SET(b, c, d, a, 7, 22, T8);
|
||||
SET(a, b, c, d, 8, 7, T9);
|
||||
SET(d, a, b, c, 9, 12, T10);
|
||||
SET(c, d, a, b, 10, 17, T11);
|
||||
SET(b, c, d, a, 11, 22, T12);
|
||||
SET(a, b, c, d, 12, 7, T13);
|
||||
SET(d, a, b, c, 13, 12, T14);
|
||||
SET(c, d, a, b, 14, 17, T15);
|
||||
SET(b, c, d, a, 15, 22, T16);
|
||||
#undef SET
|
||||
|
||||
/* Round 2. */
|
||||
/* Let [abcd k s i] denote the operation
|
||||
a = b + ((a + G(b,c,d) + X[k] + T[i]) <<< s). */
|
||||
#define G(x, y, z) (((x) & (z)) | ((y) & ~(z)))
|
||||
#define SET(a, b, c, d, k, s, Ti)\
|
||||
t = a + G(b,c,d) + X[k] + Ti;\
|
||||
a = ROTATE_LEFT(t, s) + b
|
||||
/* Do the following 16 operations. */
|
||||
SET(a, b, c, d, 1, 5, T17);
|
||||
SET(d, a, b, c, 6, 9, T18);
|
||||
SET(c, d, a, b, 11, 14, T19);
|
||||
SET(b, c, d, a, 0, 20, T20);
|
||||
SET(a, b, c, d, 5, 5, T21);
|
||||
SET(d, a, b, c, 10, 9, T22);
|
||||
SET(c, d, a, b, 15, 14, T23);
|
||||
SET(b, c, d, a, 4, 20, T24);
|
||||
SET(a, b, c, d, 9, 5, T25);
|
||||
SET(d, a, b, c, 14, 9, T26);
|
||||
SET(c, d, a, b, 3, 14, T27);
|
||||
SET(b, c, d, a, 8, 20, T28);
|
||||
SET(a, b, c, d, 13, 5, T29);
|
||||
SET(d, a, b, c, 2, 9, T30);
|
||||
SET(c, d, a, b, 7, 14, T31);
|
||||
SET(b, c, d, a, 12, 20, T32);
|
||||
#undef SET
|
||||
|
||||
/* Round 3. */
|
||||
/* Let [abcd k s t] denote the operation
|
||||
a = b + ((a + H(b,c,d) + X[k] + T[i]) <<< s). */
|
||||
#define H(x, y, z) ((x) ^ (y) ^ (z))
|
||||
#define SET(a, b, c, d, k, s, Ti)\
|
||||
t = a + H(b,c,d) + X[k] + Ti;\
|
||||
a = ROTATE_LEFT(t, s) + b
|
||||
/* Do the following 16 operations. */
|
||||
SET(a, b, c, d, 5, 4, T33);
|
||||
SET(d, a, b, c, 8, 11, T34);
|
||||
SET(c, d, a, b, 11, 16, T35);
|
||||
SET(b, c, d, a, 14, 23, T36);
|
||||
SET(a, b, c, d, 1, 4, T37);
|
||||
SET(d, a, b, c, 4, 11, T38);
|
||||
SET(c, d, a, b, 7, 16, T39);
|
||||
SET(b, c, d, a, 10, 23, T40);
|
||||
SET(a, b, c, d, 13, 4, T41);
|
||||
SET(d, a, b, c, 0, 11, T42);
|
||||
SET(c, d, a, b, 3, 16, T43);
|
||||
SET(b, c, d, a, 6, 23, T44);
|
||||
SET(a, b, c, d, 9, 4, T45);
|
||||
SET(d, a, b, c, 12, 11, T46);
|
||||
SET(c, d, a, b, 15, 16, T47);
|
||||
SET(b, c, d, a, 2, 23, T48);
|
||||
#undef SET
|
||||
|
||||
/* Round 4. */
|
||||
/* Let [abcd k s t] denote the operation
|
||||
a = b + ((a + I(b,c,d) + X[k] + T[i]) <<< s). */
|
||||
#define I(x, y, z) ((y) ^ ((x) | ~(z)))
|
||||
#define SET(a, b, c, d, k, s, Ti)\
|
||||
t = a + I(b,c,d) + X[k] + Ti;\
|
||||
a = ROTATE_LEFT(t, s) + b
|
||||
/* Do the following 16 operations. */
|
||||
SET(a, b, c, d, 0, 6, T49);
|
||||
SET(d, a, b, c, 7, 10, T50);
|
||||
SET(c, d, a, b, 14, 15, T51);
|
||||
SET(b, c, d, a, 5, 21, T52);
|
||||
SET(a, b, c, d, 12, 6, T53);
|
||||
SET(d, a, b, c, 3, 10, T54);
|
||||
SET(c, d, a, b, 10, 15, T55);
|
||||
SET(b, c, d, a, 1, 21, T56);
|
||||
SET(a, b, c, d, 8, 6, T57);
|
||||
SET(d, a, b, c, 15, 10, T58);
|
||||
SET(c, d, a, b, 6, 15, T59);
|
||||
SET(b, c, d, a, 13, 21, T60);
|
||||
SET(a, b, c, d, 4, 6, T61);
|
||||
SET(d, a, b, c, 11, 10, T62);
|
||||
SET(c, d, a, b, 2, 15, T63);
|
||||
SET(b, c, d, a, 9, 21, T64);
|
||||
#undef SET
|
||||
|
||||
/* Then perform the following additions. (That is increment each
|
||||
of the four registers by the value it had before this block
|
||||
was started.) */
|
||||
pms->abcd[0] += a;
|
||||
pms->abcd[1] += b;
|
||||
pms->abcd[2] += c;
|
||||
pms->abcd[3] += d;
|
||||
}
|
||||
|
||||
void
|
||||
md5_init(md5_state_t *pms)
|
||||
{
|
||||
pms->count[0] = pms->count[1] = 0;
|
||||
pms->abcd[0] = 0x67452301;
|
||||
pms->abcd[1] = /*0xefcdab89*/ T_MASK ^ 0x10325476;
|
||||
pms->abcd[2] = /*0x98badcfe*/ T_MASK ^ 0x67452301;
|
||||
pms->abcd[3] = 0x10325476;
|
||||
}
|
||||
|
||||
void
|
||||
md5_append(md5_state_t *pms, const md5_byte_t *data, int nbytes)
|
||||
{
|
||||
const md5_byte_t *p = data;
|
||||
int left = nbytes;
|
||||
int offset = (pms->count[0] >> 3) & 63;
|
||||
md5_word_t nbits = (md5_word_t)(nbytes << 3);
|
||||
|
||||
if (nbytes <= 0)
|
||||
return;
|
||||
|
||||
/* Update the message length. */
|
||||
pms->count[1] += nbytes >> 29;
|
||||
pms->count[0] += nbits;
|
||||
if (pms->count[0] < nbits)
|
||||
++pms->count[1];
|
||||
|
||||
/* Process an initial partial block. */
|
||||
if (offset)
|
||||
{
|
||||
int copy = (offset + nbytes > 64 ? 64 - offset : nbytes);
|
||||
|
||||
memcpy(pms->buf + offset, p, copy);
|
||||
if (offset + copy < 64)
|
||||
return;
|
||||
p += copy;
|
||||
left -= copy;
|
||||
md5_process(pms, pms->buf);
|
||||
}
|
||||
|
||||
/* Process full blocks. */
|
||||
for (; left >= 64; p += 64, left -= 64)
|
||||
md5_process(pms, p);
|
||||
|
||||
/* Process a final partial block. */
|
||||
if (left)
|
||||
memcpy(pms->buf, p, left);
|
||||
}
|
||||
|
||||
void
|
||||
md5_finish(md5_state_t *pms, md5_byte_t digest[16])
|
||||
{
|
||||
static const md5_byte_t pad[64] =
|
||||
{
|
||||
0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
|
||||
};
|
||||
md5_byte_t data[8];
|
||||
int i;
|
||||
|
||||
/* Save the length before padding. */
|
||||
for (i = 0; i < 8; ++i)
|
||||
data[i] = (md5_byte_t)(pms->count[i >> 2] >> ((i & 3) << 3));
|
||||
/* Pad to 56 bytes mod 64. */
|
||||
md5_append(pms, pad, ((55 - (pms->count[0] >> 3)) & 63) + 1);
|
||||
/* Append the length. */
|
||||
md5_append(pms, data, 8);
|
||||
for (i = 0; i < 16; ++i)
|
||||
digest[i] = (md5_byte_t)(pms->abcd[i >> 2] >> ((i & 3) << 3));
|
||||
}
|
||||
@@ -0,0 +1,92 @@
|
||||
/*
|
||||
Copyright (C) 1999, 2002 Aladdin Enterprises. All rights reserved.
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
|
||||
L. Peter Deutsch
|
||||
[email protected]
|
||||
|
||||
*/
|
||||
/* $Id: md5.h,v 1.4 2002/04/13 19:20:28 lpd Exp $ */
|
||||
/*
|
||||
Independent implementation of MD5 (RFC 1321).
|
||||
|
||||
This code implements the MD5 Algorithm defined in RFC 1321, whose
|
||||
text is available at
|
||||
http://www.ietf.org/rfc/rfc1321.txt
|
||||
The code is derived from the text of the RFC, including the test suite
|
||||
(section A.5) but excluding the rest of Appendix A. It does not include
|
||||
any code or documentation that is identified in the RFC as being
|
||||
copyrighted.
|
||||
|
||||
The original and principal author of md5.h is L. Peter Deutsch
|
||||
<[email protected]>. Other authors are noted in the change history
|
||||
that follows (in reverse chronological order):
|
||||
|
||||
2002-04-13 lpd Removed support for non-ANSI compilers; removed
|
||||
references to Ghostscript; clarified derivation from RFC 1321;
|
||||
now handles byte order either statically or dynamically.
|
||||
1999-11-04 lpd Edited comments slightly for automatic TOC extraction.
|
||||
1999-10-18 lpd Fixed typo in header comment (ansi2knr rather than md5);
|
||||
added conditionalization for C++ compilation from Martin
|
||||
Purschke <[email protected]>.
|
||||
1999-05-03 lpd Original version.
|
||||
*/
|
||||
|
||||
#ifndef md5_INCLUDED
|
||||
# define md5_INCLUDED
|
||||
|
||||
/*
|
||||
* This package supports both compile-time and run-time determination of CPU
|
||||
* byte order. If ARCH_IS_BIG_ENDIAN is defined as 0, the code will be
|
||||
* compiled to run only on little-endian CPUs; if ARCH_IS_BIG_ENDIAN is
|
||||
* defined as non-zero, the code will be compiled to run only on big-endian
|
||||
* CPUs; if ARCH_IS_BIG_ENDIAN is not defined, the code will be compiled to
|
||||
* run on either big- or little-endian CPUs, but will run slightly less
|
||||
* efficiently on either one than if ARCH_IS_BIG_ENDIAN is defined.
|
||||
*/
|
||||
|
||||
typedef unsigned char md5_byte_t; /* 8-bit byte */
|
||||
typedef unsigned int md5_word_t; /* 32-bit word */
|
||||
|
||||
/* Define the state of the MD5 Algorithm. */
|
||||
typedef struct md5_state_s
|
||||
{
|
||||
md5_word_t count[2]; /* message length in bits, lsw first */
|
||||
md5_word_t abcd[4]; /* digest buffer */
|
||||
md5_byte_t buf[64]; /* accumulate block */
|
||||
} md5_state_t;
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
/* Initialize the algorithm. */
|
||||
void md5_init(md5_state_t *pms);
|
||||
|
||||
/* Append a string to the message. */
|
||||
void md5_append(md5_state_t *pms, const md5_byte_t *data, int nbytes);
|
||||
|
||||
/* Finish the message and return the digest. */
|
||||
void md5_finish(md5_state_t *pms, md5_byte_t digest[16]);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* end extern "C" */
|
||||
#endif
|
||||
#endif /* md5_INCLUDED */
|
||||
|
||||
@@ -0,0 +1,601 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
|
||||
*
|
||||
* Copyright (C) 2008-2010 Trinity <http://www.trinitycore.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; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef _BYTEBUFFER_H
|
||||
#define _BYTEBUFFER_H
|
||||
|
||||
#include "Common.h"
|
||||
#include "Errors.h"
|
||||
#include "Log.h"
|
||||
#include "Utilities/ByteConverter.h"
|
||||
|
||||
class ByteBufferException
|
||||
{
|
||||
public:
|
||||
ByteBufferException(bool _add, size_t _pos, size_t _esize, size_t _size)
|
||||
: add(_add), pos(_pos), esize(_esize), size(_size)
|
||||
{
|
||||
PrintPosError();
|
||||
}
|
||||
|
||||
void PrintPosError() const
|
||||
{
|
||||
sLog.outError("ERROR: Attempted to %s in ByteBuffer (pos: " SIZEFMTD " size: "SIZEFMTD") value with size: " SIZEFMTD,
|
||||
(add ? "put" : "get"), pos, size, esize);
|
||||
}
|
||||
private:
|
||||
bool add;
|
||||
size_t pos;
|
||||
size_t esize;
|
||||
size_t size;
|
||||
};
|
||||
|
||||
class ByteBuffer
|
||||
{
|
||||
public:
|
||||
const static size_t DEFAULT_SIZE = 0x1000;
|
||||
|
||||
// constructor
|
||||
ByteBuffer(): _rpos(0), _wpos(0)
|
||||
{
|
||||
_storage.reserve(DEFAULT_SIZE);
|
||||
}
|
||||
|
||||
// constructor
|
||||
ByteBuffer(size_t res): _rpos(0), _wpos(0)
|
||||
{
|
||||
_storage.reserve(res);
|
||||
}
|
||||
|
||||
// copy constructor
|
||||
ByteBuffer(const ByteBuffer &buf): _rpos(buf._rpos), _wpos(buf._wpos), _storage(buf._storage) { }
|
||||
|
||||
void clear()
|
||||
{
|
||||
_storage.clear();
|
||||
_rpos = _wpos = 0;
|
||||
}
|
||||
|
||||
template <typename T> void append(T value)
|
||||
{
|
||||
EndianConvert(value);
|
||||
append((uint8 *)&value, sizeof(value));
|
||||
}
|
||||
|
||||
template <typename T> void put(size_t pos,T value)
|
||||
{
|
||||
EndianConvert(value);
|
||||
put(pos,(uint8 *)&value,sizeof(value));
|
||||
}
|
||||
|
||||
ByteBuffer &operator<<(uint8 value)
|
||||
{
|
||||
append<uint8>(value);
|
||||
return *this;
|
||||
}
|
||||
|
||||
ByteBuffer &operator<<(uint16 value)
|
||||
{
|
||||
append<uint16>(value);
|
||||
return *this;
|
||||
}
|
||||
|
||||
ByteBuffer &operator<<(uint32 value)
|
||||
{
|
||||
append<uint32>(value);
|
||||
return *this;
|
||||
}
|
||||
|
||||
ByteBuffer &operator<<(uint64 value)
|
||||
{
|
||||
append<uint64>(value);
|
||||
return *this;
|
||||
}
|
||||
|
||||
// signed as in 2e complement
|
||||
ByteBuffer &operator<<(int8 value)
|
||||
{
|
||||
append<int8>(value);
|
||||
return *this;
|
||||
}
|
||||
|
||||
ByteBuffer &operator<<(int16 value)
|
||||
{
|
||||
append<int16>(value);
|
||||
return *this;
|
||||
}
|
||||
|
||||
ByteBuffer &operator<<(int32 value)
|
||||
{
|
||||
append<int32>(value);
|
||||
return *this;
|
||||
}
|
||||
|
||||
ByteBuffer &operator<<(int64 value)
|
||||
{
|
||||
append<int64>(value);
|
||||
return *this;
|
||||
}
|
||||
|
||||
// floating points
|
||||
ByteBuffer &operator<<(float value)
|
||||
{
|
||||
append<float>(value);
|
||||
return *this;
|
||||
}
|
||||
|
||||
ByteBuffer &operator<<(double value)
|
||||
{
|
||||
append<double>(value);
|
||||
return *this;
|
||||
}
|
||||
|
||||
ByteBuffer &operator<<(const std::string &value)
|
||||
{
|
||||
append((uint8 const *)value.c_str(), value.length());
|
||||
append((uint8)0);
|
||||
return *this;
|
||||
}
|
||||
|
||||
ByteBuffer &operator<<(const char *str)
|
||||
{
|
||||
append((uint8 const *)str, str ? strlen(str) : 0);
|
||||
append((uint8)0);
|
||||
return *this;
|
||||
}
|
||||
|
||||
ByteBuffer &operator>>(bool &value)
|
||||
{
|
||||
value = read<char>() > 0 ? true : false;
|
||||
return *this;
|
||||
}
|
||||
|
||||
ByteBuffer &operator>>(uint8 &value)
|
||||
{
|
||||
value = read<uint8>();
|
||||
return *this;
|
||||
}
|
||||
|
||||
ByteBuffer &operator>>(uint16 &value)
|
||||
{
|
||||
value = read<uint16>();
|
||||
return *this;
|
||||
}
|
||||
|
||||
ByteBuffer &operator>>(uint32 &value)
|
||||
{
|
||||
value = read<uint32>();
|
||||
return *this;
|
||||
}
|
||||
|
||||
ByteBuffer &operator>>(uint64 &value)
|
||||
{
|
||||
value = read<uint64>();
|
||||
return *this;
|
||||
}
|
||||
|
||||
//signed as in 2e complement
|
||||
ByteBuffer &operator>>(int8 &value)
|
||||
{
|
||||
value = read<int8>();
|
||||
return *this;
|
||||
}
|
||||
|
||||
ByteBuffer &operator>>(int16 &value)
|
||||
{
|
||||
value = read<int16>();
|
||||
return *this;
|
||||
}
|
||||
|
||||
ByteBuffer &operator>>(int32 &value)
|
||||
{
|
||||
value = read<int32>();
|
||||
return *this;
|
||||
}
|
||||
|
||||
ByteBuffer &operator>>(int64 &value)
|
||||
{
|
||||
value = read<int64>();
|
||||
return *this;
|
||||
}
|
||||
|
||||
ByteBuffer &operator>>(float &value)
|
||||
{
|
||||
value = read<float>();
|
||||
return *this;
|
||||
}
|
||||
|
||||
ByteBuffer &operator>>(double &value)
|
||||
{
|
||||
value = read<double>();
|
||||
return *this;
|
||||
}
|
||||
|
||||
ByteBuffer &operator>>(std::string& value)
|
||||
{
|
||||
value.clear();
|
||||
while (rpos() < size()) // prevent crash at wrong string format in packet
|
||||
{
|
||||
char c = read<char>();
|
||||
if (c == 0)
|
||||
break;
|
||||
value += c;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
uint8 operator[](size_t pos) const
|
||||
{
|
||||
return read<uint8>(pos);
|
||||
}
|
||||
|
||||
size_t rpos() const { return _rpos; }
|
||||
|
||||
size_t rpos(size_t rpos_)
|
||||
{
|
||||
_rpos = rpos_;
|
||||
return _rpos;
|
||||
}
|
||||
|
||||
size_t wpos() const { return _wpos; }
|
||||
|
||||
size_t wpos(size_t wpos_)
|
||||
{
|
||||
_wpos = wpos_;
|
||||
return _wpos;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void read_skip() { read_skip(sizeof(T)); }
|
||||
|
||||
void read_skip(size_t skip)
|
||||
{
|
||||
if(_rpos + skip > size())
|
||||
throw ByteBufferException(false, _rpos, skip, size());
|
||||
_rpos += skip;
|
||||
}
|
||||
|
||||
template <typename T> T read()
|
||||
{
|
||||
T r = read<T>(_rpos);
|
||||
_rpos += sizeof(T);
|
||||
return r;
|
||||
}
|
||||
|
||||
template <typename T> T read(size_t pos) const
|
||||
{
|
||||
if(pos + sizeof(T) > size())
|
||||
throw ByteBufferException(false, pos, sizeof(T), size());
|
||||
T val = *((T const*)&_storage[pos]);
|
||||
EndianConvert(val);
|
||||
return val;
|
||||
}
|
||||
|
||||
void read(uint8 *dest, size_t len)
|
||||
{
|
||||
if(_rpos + len > size())
|
||||
throw ByteBufferException(false, _rpos, len, size());
|
||||
memcpy(dest, &_storage[_rpos], len);
|
||||
_rpos += len;
|
||||
}
|
||||
|
||||
bool readPackGUID(uint64& guid)
|
||||
{
|
||||
if(rpos() + 1 > size())
|
||||
return false;
|
||||
|
||||
guid = 0;
|
||||
|
||||
uint8 guidmark = 0;
|
||||
(*this) >> guidmark;
|
||||
|
||||
for (int i = 0; i < 8; ++i)
|
||||
{
|
||||
if(guidmark & (uint8(1) << i))
|
||||
{
|
||||
if(rpos() + 1 > size())
|
||||
return false;
|
||||
|
||||
uint8 bit;
|
||||
(*this) >> bit;
|
||||
guid |= (uint64(bit) << (i * 8));
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
const uint8 *contents() const { return &_storage[0]; }
|
||||
|
||||
size_t size() const { return _storage.size(); }
|
||||
bool empty() const { return _storage.empty(); }
|
||||
|
||||
void resize(size_t newsize)
|
||||
{
|
||||
_storage.resize(newsize);
|
||||
_rpos = 0;
|
||||
_wpos = size();
|
||||
}
|
||||
|
||||
void reserve(size_t ressize)
|
||||
{
|
||||
if (ressize > size())
|
||||
_storage.reserve(ressize);
|
||||
}
|
||||
|
||||
void append(const std::string& str)
|
||||
{
|
||||
append((uint8 const*)str.c_str(), str.size() + 1);
|
||||
}
|
||||
|
||||
void append(const char *src, size_t cnt)
|
||||
{
|
||||
return append((const uint8 *)src, cnt);
|
||||
}
|
||||
|
||||
template<class T> void append(const T *src, size_t cnt)
|
||||
{
|
||||
return append((const uint8 *)src, cnt * sizeof(T));
|
||||
}
|
||||
|
||||
void append(const uint8 *src, size_t cnt)
|
||||
{
|
||||
if (!cnt)
|
||||
return;
|
||||
|
||||
ASSERT(size() < 10000000);
|
||||
|
||||
if (_storage.size() < _wpos + cnt)
|
||||
_storage.resize(_wpos + cnt);
|
||||
memcpy(&_storage[_wpos], src, cnt);
|
||||
_wpos += cnt;
|
||||
}
|
||||
|
||||
void append(const ByteBuffer& buffer)
|
||||
{
|
||||
if(buffer.wpos())
|
||||
append(buffer.contents(), buffer.wpos());
|
||||
}
|
||||
|
||||
// can be used in SMSG_MONSTER_MOVE opcode
|
||||
void appendPackXYZ(float x, float y, float z)
|
||||
{
|
||||
uint32 packed = 0;
|
||||
packed |= ((int)(x / 0.25f) & 0x7FF);
|
||||
packed |= ((int)(y / 0.25f) & 0x7FF) << 11;
|
||||
packed |= ((int)(z / 0.25f) & 0x3FF) << 22;
|
||||
*this << packed;
|
||||
}
|
||||
|
||||
void appendPackGUID(uint64 guid)
|
||||
{
|
||||
uint8 packGUID[8+1];
|
||||
packGUID[0] = 0;
|
||||
size_t size = 1;
|
||||
for(uint8 i = 0;guid != 0;++i)
|
||||
{
|
||||
if(guid & 0xFF)
|
||||
{
|
||||
packGUID[0] |= uint8(1 << i);
|
||||
packGUID[size] = uint8(guid & 0xFF);
|
||||
++size;
|
||||
}
|
||||
|
||||
guid >>= 8;
|
||||
}
|
||||
append(packGUID, size);
|
||||
}
|
||||
|
||||
void put(size_t pos, const uint8 *src, size_t cnt)
|
||||
{
|
||||
if(pos + cnt > size())
|
||||
throw ByteBufferException(true, pos, cnt, size());
|
||||
memcpy(&_storage[pos], src, cnt);
|
||||
}
|
||||
|
||||
void print_storage() const
|
||||
{
|
||||
if(!sLog.IsOutDebug()) // optimize disabled debug output
|
||||
return;
|
||||
|
||||
sLog.outDebug("STORAGE_SIZE: %lu", (unsigned long)size() );
|
||||
for (uint32 i = 0; i < size(); ++i)
|
||||
sLog.outDebugInLine("%u - ", read<uint8>(i) );
|
||||
sLog.outDebug(" ");
|
||||
}
|
||||
|
||||
void textlike() const
|
||||
{
|
||||
if(!sLog.IsOutDebug()) // optimize disabled debug output
|
||||
return;
|
||||
|
||||
sLog.outDebug("STORAGE_SIZE: %lu", (unsigned long)size() );
|
||||
for (uint32 i = 0; i < size(); ++i)
|
||||
sLog.outDebugInLine("%c", read<uint8>(i) );
|
||||
sLog.outDebug(" ");
|
||||
}
|
||||
|
||||
void hexlike() const
|
||||
{
|
||||
if(!sLog.IsOutDebug()) // optimize disabled debug output
|
||||
return;
|
||||
|
||||
uint32 j = 1, k = 1;
|
||||
sLog.outDebug("STORAGE_SIZE: %lu", (unsigned long)size() );
|
||||
|
||||
for (uint32 i = 0; i < size(); ++i)
|
||||
{
|
||||
if ((i == (j * 8)) && ((i != (k * 16))))
|
||||
{
|
||||
if (read<uint8>(i) < 0x10)
|
||||
{
|
||||
sLog.outDebugInLine("| 0%X ", read<uint8>(i) );
|
||||
}
|
||||
else
|
||||
{
|
||||
sLog.outDebugInLine("| %X ", read<uint8>(i) );
|
||||
}
|
||||
++j;
|
||||
}
|
||||
else if (i == (k * 16))
|
||||
{
|
||||
if (read<uint8>(i) < 0x10)
|
||||
{
|
||||
sLog.outDebugInLine("\n");
|
||||
|
||||
sLog.outDebugInLine("0%X ", read<uint8>(i) );
|
||||
}
|
||||
else
|
||||
{
|
||||
sLog.outDebugInLine("\n");
|
||||
|
||||
sLog.outDebugInLine("%X ", read<uint8>(i) );
|
||||
}
|
||||
|
||||
++k;
|
||||
++j;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (read<uint8>(i) < 0x10)
|
||||
{
|
||||
sLog.outDebugInLine("0%X ", read<uint8>(i) );
|
||||
}
|
||||
else
|
||||
{
|
||||
sLog.outDebugInLine("%X ", read<uint8>(i) );
|
||||
}
|
||||
}
|
||||
}
|
||||
sLog.outDebugInLine("\n");
|
||||
}
|
||||
|
||||
protected:
|
||||
size_t _rpos, _wpos;
|
||||
std::vector<uint8> _storage;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
inline ByteBuffer &operator<<(ByteBuffer &b, std::vector<T> v)
|
||||
{
|
||||
b << (uint32)v.size();
|
||||
for (typename std::vector<T>::iterator i = v.begin(); i != v.end(); ++i)
|
||||
{
|
||||
b << *i;
|
||||
}
|
||||
return b;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline ByteBuffer &operator>>(ByteBuffer &b, std::vector<T> &v)
|
||||
{
|
||||
uint32 vsize;
|
||||
b >> vsize;
|
||||
v.clear();
|
||||
while(vsize--)
|
||||
{
|
||||
T t;
|
||||
b >> t;
|
||||
v.push_back(t);
|
||||
}
|
||||
return b;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline ByteBuffer &operator<<(ByteBuffer &b, std::list<T> v)
|
||||
{
|
||||
b << (uint32)v.size();
|
||||
for (typename std::list<T>::iterator i = v.begin(); i != v.end(); ++i)
|
||||
{
|
||||
b << *i;
|
||||
}
|
||||
return b;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline ByteBuffer &operator>>(ByteBuffer &b, std::list<T> &v)
|
||||
{
|
||||
uint32 vsize;
|
||||
b >> vsize;
|
||||
v.clear();
|
||||
while(vsize--)
|
||||
{
|
||||
T t;
|
||||
b >> t;
|
||||
v.push_back(t);
|
||||
}
|
||||
return b;
|
||||
}
|
||||
|
||||
template <typename K, typename V>
|
||||
inline ByteBuffer &operator<<(ByteBuffer &b, std::map<K, V> &m)
|
||||
{
|
||||
b << (uint32)m.size();
|
||||
for (typename std::map<K, V>::iterator i = m.begin(); i != m.end(); ++i)
|
||||
{
|
||||
b << i->first << i->second;
|
||||
}
|
||||
return b;
|
||||
}
|
||||
|
||||
template <typename K, typename V>
|
||||
inline ByteBuffer &operator>>(ByteBuffer &b, std::map<K, V> &m)
|
||||
{
|
||||
uint32 msize;
|
||||
b >> msize;
|
||||
m.clear();
|
||||
while(msize--)
|
||||
{
|
||||
K k;
|
||||
V v;
|
||||
b >> k >> v;
|
||||
m.insert(make_pair(k, v));
|
||||
}
|
||||
return b;
|
||||
}
|
||||
|
||||
// TODO: Make a ByteBuffer.cpp and move all this inlining to it.
|
||||
template<> inline std::string ByteBuffer::read<std::string>()
|
||||
{
|
||||
std::string tmp;
|
||||
*this >> tmp;
|
||||
return tmp;
|
||||
}
|
||||
|
||||
template<>
|
||||
inline void ByteBuffer::read_skip<char*>()
|
||||
{
|
||||
std::string temp;
|
||||
*this >> temp;
|
||||
}
|
||||
|
||||
template<>
|
||||
inline void ByteBuffer::read_skip<char const*>()
|
||||
{
|
||||
read_skip<char*>();
|
||||
}
|
||||
|
||||
template<>
|
||||
inline void ByteBuffer::read_skip<std::string>()
|
||||
{
|
||||
read_skip<char*>();
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
add_subdirectory(vmap)
|
||||
add_subdirectory(Auth)
|
||||
add_subdirectory(Config)
|
||||
add_subdirectory(Database)
|
||||
|
||||
########### next target ###############
|
||||
|
||||
SET(shared_STAT_SRCS
|
||||
ByteBuffer.h
|
||||
Common.cpp
|
||||
Common.h
|
||||
DelayExecutor.cpp
|
||||
DelayExecutor.h
|
||||
Errors.h
|
||||
Log.cpp
|
||||
Log.h
|
||||
ProgressBar.cpp
|
||||
ProgressBar.h
|
||||
SignalHandler.h
|
||||
Threading.cpp
|
||||
Timer.h
|
||||
Util.cpp
|
||||
Util.h
|
||||
WorldPacket.h
|
||||
SystemConfig.h
|
||||
)
|
||||
|
||||
include_directories(
|
||||
${ACE_INCLUDE_DIR}
|
||||
${CMAKE_BINARY_DIR}
|
||||
${CMAKE_SOURCE_DIR}/dep/include
|
||||
${CMAKE_SOURCE_DIR}/dep/include/sockets
|
||||
${CMAKE_SOURCE_DIR}/src/framework
|
||||
${CMAKE_SOURCE_DIR}/src/shared
|
||||
${MYSQL_INCLUDE_DIR}
|
||||
)
|
||||
|
||||
add_library(shared STATIC ${shared_STAT_SRCS})
|
||||
target_link_libraries(
|
||||
shared
|
||||
${ACE_LIBRARY}
|
||||
)
|
||||
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
|
||||
*
|
||||
* Copyright (C) 2008-2010 Trinity <http://www.trinitycore.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; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include "Common.h"
|
||||
|
||||
char const* localeNames[MAX_LOCALE] = {
|
||||
"enUS",
|
||||
"koKR",
|
||||
"frFR",
|
||||
"deDE",
|
||||
"zhCN",
|
||||
"zhTW",
|
||||
"esES",
|
||||
"esMX",
|
||||
"ruRU"
|
||||
};
|
||||
|
||||
LocaleConstant GetLocaleByName(const std::string& name)
|
||||
{
|
||||
for (uint32 i = 0; i < MAX_LOCALE; ++i)
|
||||
if(name==localeNames[i])
|
||||
return LocaleConstant(i);
|
||||
|
||||
return LOCALE_enUS; // including enGB case
|
||||
}
|
||||
|
||||
@@ -0,0 +1,216 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
|
||||
*
|
||||
* Copyright (C) 2008-2010 Trinity <http://www.trinitycore.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; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public 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 TRINITYCORE_COMMON_H
|
||||
#define TRINITYCORE_COMMON_H
|
||||
|
||||
// config.h needs to be included 1st
|
||||
// TODO this thingy looks like hack ,but its not, need to
|
||||
// make separate header however, because It makes mess here.
|
||||
#ifdef HAVE_CONFIG_H
|
||||
// Remove Some things that we will define
|
||||
// This is in case including another config.h
|
||||
// before trinity config.h
|
||||
#ifdef PACKAGE
|
||||
#undef PACKAGE
|
||||
#endif //PACKAGE
|
||||
#ifdef PACKAGE_BUGREPORT
|
||||
#undef PACKAGE_BUGREPORT
|
||||
#endif //PACKAGE_BUGREPORT
|
||||
#ifdef PACKAGE_NAME
|
||||
#undef PACKAGE_NAME
|
||||
#endif //PACKAGE_NAME
|
||||
#ifdef PACKAGE_STRING
|
||||
#undef PACKAGE_STRING
|
||||
#endif //PACKAGE_STRING
|
||||
#ifdef PACKAGE_TARNAME
|
||||
#undef PACKAGE_TARNAME
|
||||
#endif //PACKAGE_TARNAME
|
||||
#ifdef PACKAGE_VERSION
|
||||
#undef PACKAGE_VERSION
|
||||
#endif //PACKAGE_VERSION
|
||||
#ifdef VERSION
|
||||
#undef VERSION
|
||||
#endif //VERSION
|
||||
# include "config.h"
|
||||
#undef PACKAGE
|
||||
#undef PACKAGE_BUGREPORT
|
||||
#undef PACKAGE_NAME
|
||||
#undef PACKAGE_STRING
|
||||
#undef PACKAGE_TARNAME
|
||||
#undef PACKAGE_VERSION
|
||||
#undef VERSION
|
||||
#endif //HAVE_CONFIG_H
|
||||
|
||||
#include "Platform/Define.h"
|
||||
|
||||
#if COMPILER == COMPILER_MICROSOFT
|
||||
# pragma warning(disable:4996) // 'function': was declared deprecated
|
||||
#ifndef __SHOW_STUPID_WARNINGS__
|
||||
# pragma warning(disable:4005) // 'identifier' : macro redefinition
|
||||
# pragma warning(disable:4018) // 'expression' : signed/unsigned mismatch
|
||||
# pragma warning(disable:4244) // 'argument' : conversion from 'type1' to 'type2', possible loss of data
|
||||
# pragma warning(disable:4267) // 'var' : conversion from 'size_t' to 'type', possible loss of data
|
||||
# pragma warning(disable:4305) // 'identifier' : truncation from 'type1' to 'type2'
|
||||
# pragma warning(disable:4311) // 'variable' : pointer truncation from 'type' to 'type'
|
||||
# pragma warning(disable:4355) // 'this' : used in base member initializer list
|
||||
# pragma warning(disable:4800) // 'type' : forcing value to bool 'true' or 'false' (performance warning)
|
||||
# pragma warning(disable:4522) //warning when class has 2 constructors
|
||||
#endif // __SHOW_STUPID_WARNINGS__
|
||||
#endif // __GNUC__
|
||||
|
||||
#include "Utilities/UnorderedMap.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
#include <math.h>
|
||||
#include <errno.h>
|
||||
#include <signal.h>
|
||||
#include <assert.h>
|
||||
|
||||
#if PLATFORM == PLATFORM_WINDOWS
|
||||
#define STRCASECMP stricmp
|
||||
#else
|
||||
#define STRCASECMP strcasecmp
|
||||
#endif
|
||||
|
||||
#include <set>
|
||||
#include <list>
|
||||
#include <string>
|
||||
#include <map>
|
||||
#include <queue>
|
||||
#include <sstream>
|
||||
#include <algorithm>
|
||||
|
||||
#include "LockedQueue.h"
|
||||
#include "Threading.h"
|
||||
|
||||
#include <ace/Basic_Types.h>
|
||||
#include <ace/Guard_T.h>
|
||||
#include <ace/RW_Thread_Mutex.h>
|
||||
#include <ace/Thread_Mutex.h>
|
||||
|
||||
#if PLATFORM == PLATFORM_WINDOWS
|
||||
# define FD_SETSIZE 4096
|
||||
# include <ace/config-all.h>
|
||||
// XP winver - needed to compile with standard leak check in MemoryLeaks.h
|
||||
// uncomment later if needed
|
||||
//#define _WIN32_WINNT 0x0501
|
||||
# include <ws2tcpip.h>
|
||||
//#undef WIN32_WINNT
|
||||
#else
|
||||
# include <sys/types.h>
|
||||
# include <sys/ioctl.h>
|
||||
# include <sys/socket.h>
|
||||
# include <netinet/in.h>
|
||||
# include <unistd.h>
|
||||
# include <netdb.h>
|
||||
#endif
|
||||
|
||||
#if COMPILER == COMPILER_MICROSOFT
|
||||
|
||||
#include <float.h>
|
||||
|
||||
#define I32FMT "%08I32X"
|
||||
#define I64FMT "%016I64X"
|
||||
#define snprintf _snprintf
|
||||
#define atoll __atoi64
|
||||
#define vsnprintf _vsnprintf
|
||||
#define strdup _strdup
|
||||
#define finite(X) _finite(X)
|
||||
|
||||
#else
|
||||
|
||||
#define stricmp strcasecmp
|
||||
#define strnicmp strncasecmp
|
||||
#define I32FMT "%08X"
|
||||
#define I64FMT "%016llX"
|
||||
|
||||
#endif
|
||||
|
||||
#define UI64FMTD ACE_UINT64_FORMAT_SPECIFIER
|
||||
#define UI64LIT(N) ACE_UINT64_LITERAL(N)
|
||||
|
||||
#define SI64FMTD ACE_INT64_FORMAT_SPECIFIER
|
||||
#define SI64LIT(N) ACE_INT64_LITERAL(N)
|
||||
|
||||
#define SIZEFMTD ACE_SIZE_T_FORMAT_SPECIFIER
|
||||
|
||||
inline float finiteAlways(float f) { return finite(f) ? f : 0.0f; }
|
||||
|
||||
#define atol(a) strtoul( a, NULL, 10)
|
||||
|
||||
#define STRINGIZE(a) #a
|
||||
|
||||
enum TimeConstants
|
||||
{
|
||||
MINUTE = 60,
|
||||
HOUR = MINUTE*60,
|
||||
DAY = HOUR*24,
|
||||
WEEK = DAY*7,
|
||||
MONTH = DAY*30,
|
||||
YEAR = MONTH*12,
|
||||
IN_MILISECONDS = 1000
|
||||
};
|
||||
|
||||
enum AccountTypes
|
||||
{
|
||||
SEC_PLAYER = 0,
|
||||
SEC_MODERATOR = 1,
|
||||
SEC_GAMEMASTER = 2,
|
||||
SEC_ADMINISTRATOR = 3,
|
||||
SEC_CONSOLE = 4 // must be always last in list, accounts must have less security level always also
|
||||
};
|
||||
|
||||
enum LocaleConstant
|
||||
{
|
||||
LOCALE_enUS = 0,
|
||||
LOCALE_koKR = 1,
|
||||
LOCALE_frFR = 2,
|
||||
LOCALE_deDE = 3,
|
||||
LOCALE_zhCN = 4,
|
||||
LOCALE_zhTW = 5,
|
||||
LOCALE_esES = 6,
|
||||
LOCALE_esMX = 7,
|
||||
LOCALE_ruRU = 8
|
||||
};
|
||||
|
||||
const uint8 MAX_LOCALE = 9;
|
||||
|
||||
extern char const* localeNames[MAX_LOCALE];
|
||||
|
||||
LocaleConstant GetLocaleByName(const std::string& name);
|
||||
|
||||
// we always use stdlibc++ std::max/std::min, undefine some not C++ standard defines (Win API and some other platforms)
|
||||
#ifdef max
|
||||
#undef max
|
||||
#endif
|
||||
|
||||
#ifdef min
|
||||
#undef min
|
||||
#endif
|
||||
|
||||
#ifndef M_PI
|
||||
#define M_PI 3.14159265358979323846
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
|
||||
########### next target ###############
|
||||
|
||||
SET(trinityconfig_STAT_SRCS
|
||||
dotconfpp/dotconfpp.cpp
|
||||
dotconfpp/dotconfpp.h
|
||||
dotconfpp/mempool.cpp
|
||||
dotconfpp/mempool.h
|
||||
Config.cpp
|
||||
Config.h
|
||||
ConfigEnv.h
|
||||
)
|
||||
|
||||
include_directories(
|
||||
${ACE_INCLUDE_DIR}
|
||||
${CMAKE_BINARY_DIR}
|
||||
${CMAKE_SOURCE_DIR}/src/shared
|
||||
${CMAKE_SOURCE_DIR}/src/framework
|
||||
)
|
||||
|
||||
add_library(trinityconfig STATIC ${trinityconfig_STAT_SRCS})
|
||||
|
||||
@@ -0,0 +1,105 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
|
||||
*
|
||||
* Copyright (C) 2008-2010 Trinity <http://www.trinitycore.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; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include "ConfigEnv.h"
|
||||
#include "Policies/SingletonImp.h"
|
||||
|
||||
INSTANTIATE_SINGLETON_1(Config);
|
||||
|
||||
Config::Config() : mIgnoreCase(true), mConf(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
Config::~Config()
|
||||
{
|
||||
delete mConf;
|
||||
}
|
||||
|
||||
bool Config::SetSource(const char *file, bool ignorecase)
|
||||
{
|
||||
mIgnoreCase = ignorecase;
|
||||
mFilename = file;
|
||||
|
||||
return Reload();
|
||||
}
|
||||
|
||||
bool Config::Reload()
|
||||
{
|
||||
delete mConf;
|
||||
|
||||
mConf = new DOTCONFDocument(mIgnoreCase ?
|
||||
DOTCONFDocument::CASEINSENSETIVE :
|
||||
DOTCONFDocument::CASESENSETIVE);
|
||||
|
||||
if (mConf->setContent(mFilename.c_str()) == -1)
|
||||
{
|
||||
delete mConf;
|
||||
mConf = NULL;
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
std::string Config::GetStringDefault(const char * name, std::string def)
|
||||
{
|
||||
if(!mConf)
|
||||
return std::string(def);
|
||||
const DOTCONFDocumentNode * node = mConf->findNode(name);
|
||||
if(!node || !node->getValue())
|
||||
return std::string(def);
|
||||
return std::string(node->getValue());
|
||||
};
|
||||
|
||||
bool Config::GetBoolDefault(const char * name, const bool def)
|
||||
{
|
||||
if(!mConf)
|
||||
return false;
|
||||
const DOTCONFDocumentNode * node = mConf->findNode(name);
|
||||
if(!node || !node->getValue())
|
||||
return def;
|
||||
const char * str = node->getValue();
|
||||
if(strcmp(str, "true") == 0 || strcmp(str, "TRUE") == 0 ||
|
||||
strcmp(str, "yes") == 0 || strcmp(str, "YES") == 0 ||
|
||||
strcmp(str, "1") == 0)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
};
|
||||
|
||||
int32 Config::GetIntDefault(const char * name, const int32 def)
|
||||
{
|
||||
if(!mConf)
|
||||
return def;
|
||||
const DOTCONFDocumentNode * node = mConf->findNode(name);
|
||||
if(!node || !node->getValue())
|
||||
return def;
|
||||
return atoi(node->getValue());
|
||||
};
|
||||
|
||||
float Config::GetFloatDefault(const char * name, const float def)
|
||||
{
|
||||
if(!mConf)
|
||||
return def;
|
||||
const DOTCONFDocumentNode * node = mConf->findNode(name);
|
||||
if(!node || !node->getValue())
|
||||
return def;
|
||||
return atof(node->getValue());
|
||||
};
|
||||
@@ -0,0 +1,53 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
|
||||
*
|
||||
* Copyright (C) 2008-2010 Trinity <http://www.trinitycore.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; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef CONFIG_H
|
||||
#define CONFIG_H
|
||||
|
||||
#include <Policies/Singleton.h>
|
||||
#include "Platform/Define.h"
|
||||
|
||||
class DOTCONFDocument;
|
||||
|
||||
class Config
|
||||
{
|
||||
public:
|
||||
Config();
|
||||
~Config();
|
||||
|
||||
bool SetSource(const char *file, bool ignorecase = true);
|
||||
bool Reload();
|
||||
|
||||
std::string GetStringDefault(const char * name, std::string def);
|
||||
bool GetBoolDefault(const char * name, const bool def);
|
||||
int32 GetIntDefault(const char * name, const int32 def);
|
||||
float GetFloatDefault(const char * name, const float def);
|
||||
|
||||
std::string GetFilename() const { return mFilename; }
|
||||
private:
|
||||
std::string mFilename;
|
||||
bool mIgnoreCase;
|
||||
DOTCONFDocument *mConf;
|
||||
};
|
||||
|
||||
#define sConfig Trinity::Singleton<Config>::Instance()
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
|
||||
*
|
||||
* Copyright (C) 2008-2010 Trinity <http://www.trinitycore.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; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#if !defined(CONFIGENVIRONMENT_H)
|
||||
|
||||
#define CONFIGENVIRONMENT_H
|
||||
|
||||
#include "Common.h"
|
||||
#include "dotconfpp/dotconfpp.h"
|
||||
#include "Config.h"
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,137 @@
|
||||
<?xml version="1.0" encoding="Windows-1252"?>
|
||||
<VisualStudioProject
|
||||
ProjectType="Visual C++"
|
||||
Version="7.10"
|
||||
Name="ConfigLibrary"
|
||||
ProjectGUID="{C849D54F-32A6-4025-95BE-E64D1CF0686E}"
|
||||
Keyword="Win32Proj">
|
||||
<Platforms>
|
||||
<Platform
|
||||
Name="Win32"/>
|
||||
</Platforms>
|
||||
<Configurations>
|
||||
<Configuration
|
||||
Name="Debug|Win32"
|
||||
OutputDirectory="Debug"
|
||||
IntermediateDirectory="Debug"
|
||||
ConfigurationType="4"
|
||||
CharacterSet="2">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
AdditionalIncludeDirectories=""
|
||||
PreprocessorDefinitions="WIN32;_DEBUG;_LIB"
|
||||
MinimalRebuild="TRUE"
|
||||
BasicRuntimeChecks="3"
|
||||
RuntimeLibrary="1"
|
||||
UsePrecompiledHeader="0"
|
||||
WarningLevel="3"
|
||||
Detect64BitPortabilityProblems="TRUE"
|
||||
DebugInformationFormat="4"/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"/>
|
||||
<Tool
|
||||
Name="VCLibrarianTool"
|
||||
OutputFile="$(OutDir)/ConfigLibrary.lib"/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCManagedWrapperGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Release|Win32"
|
||||
OutputDirectory="Release"
|
||||
IntermediateDirectory="Release"
|
||||
ConfigurationType="4"
|
||||
CharacterSet="2">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AdditionalIncludeDirectories=""
|
||||
PreprocessorDefinitions="WIN32;NDEBUG;_LIB"
|
||||
RuntimeLibrary="0"
|
||||
UsePrecompiledHeader="0"
|
||||
WarningLevel="3"
|
||||
Detect64BitPortabilityProblems="TRUE"
|
||||
DebugInformationFormat="3"/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"/>
|
||||
<Tool
|
||||
Name="VCLibrarianTool"
|
||||
OutputFile="$(OutDir)/ConfigLibrary.lib"/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCManagedWrapperGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
|
||||
</Configuration>
|
||||
</Configurations>
|
||||
<References>
|
||||
</References>
|
||||
<Files>
|
||||
<Filter
|
||||
Name="Source Files"
|
||||
Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
|
||||
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}">
|
||||
<File
|
||||
RelativePath=".\Config.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\dotconfpp\dotconfpp.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\dotconfpp\mempool.cpp">
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Header Files"
|
||||
Filter="h;hpp;hxx;hm;inl;inc;xsd"
|
||||
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}">
|
||||
<File
|
||||
RelativePath=".\Config.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\ConfigEnv.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\dotconfpp\dotconfpp.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\dotconfpp\mempool.h">
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Resource Files"
|
||||
Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx"
|
||||
UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}">
|
||||
</Filter>
|
||||
</Files>
|
||||
<Globals>
|
||||
</Globals>
|
||||
</VisualStudioProject>
|
||||
@@ -0,0 +1,599 @@
|
||||
|
||||
#include "Common.h"
|
||||
|
||||
#include "dotconfpp.h"
|
||||
|
||||
#ifdef WIN32
|
||||
#define PATH_MAX _MAX_PATH
|
||||
#define strcasecmp stricmp
|
||||
#define realpath(path,resolved_path) _fullpath(resolved_path, path, _MAX_PATH)
|
||||
#include <io.h>
|
||||
#else
|
||||
#include <unistd.h>
|
||||
#include <limits.h>
|
||||
#include <stdint.h>
|
||||
#include <strings.h>
|
||||
#endif
|
||||
|
||||
#if !defined(R_OK)
|
||||
#define R_OK 04
|
||||
#endif
|
||||
|
||||
DOTCONFDocumentNode::DOTCONFDocumentNode():previousNode(NULL), nextNode(NULL), parentNode(NULL), childNode(NULL),
|
||||
values(NULL), valuesCount(0),
|
||||
name(NULL), lineNum(0), fileName(NULL), closed(true)
|
||||
{
|
||||
}
|
||||
|
||||
DOTCONFDocumentNode::~DOTCONFDocumentNode()
|
||||
{
|
||||
free(name);
|
||||
if(values != NULL){
|
||||
for (int i = 0 ; i < valuesCount; i++){
|
||||
free(values[i]);
|
||||
}
|
||||
free(values);
|
||||
}
|
||||
}
|
||||
|
||||
void DOTCONFDocumentNode::pushValue(char * _value)
|
||||
{
|
||||
++valuesCount;
|
||||
values = (char**)realloc(values, valuesCount*sizeof(char*));
|
||||
values[valuesCount-1] = strdup(_value);
|
||||
}
|
||||
|
||||
const char* DOTCONFDocumentNode::getValue(int index) const
|
||||
{
|
||||
if(index >= valuesCount){
|
||||
return NULL;
|
||||
}
|
||||
return values[index];
|
||||
}
|
||||
|
||||
DOTCONFDocument::DOTCONFDocument(DOTCONFDocument::CaseSensitive caseSensitivity):
|
||||
mempool(NULL),
|
||||
curParent(NULL), curPrev(NULL), curLine(0), file(NULL), fileName(NULL)
|
||||
{
|
||||
if(caseSensitivity == CASESENSETIVE){
|
||||
cmp_func = strcmp;
|
||||
} else {
|
||||
cmp_func = strcasecmp;
|
||||
}
|
||||
|
||||
mempool = new AsyncDNSMemPool(1024);
|
||||
mempool->initialize();
|
||||
}
|
||||
|
||||
DOTCONFDocument::~DOTCONFDocument()
|
||||
{
|
||||
for (std::list<DOTCONFDocumentNode*>::iterator i = nodeTree.begin(); i != nodeTree.end(); ++i){
|
||||
delete(*i);
|
||||
}
|
||||
for (std::list<char*>::iterator i = requiredOptions.begin(); i != requiredOptions.end(); ++i){
|
||||
free(*i);
|
||||
}
|
||||
for (std::list<char*>::iterator i = processedFiles.begin(); i != processedFiles.end(); ++i){
|
||||
free(*i);
|
||||
}
|
||||
free(fileName);
|
||||
delete mempool;
|
||||
}
|
||||
|
||||
int DOTCONFDocument::cleanupLine(char * line)
|
||||
{
|
||||
char * start = line;
|
||||
char * bg = line;
|
||||
bool multiline = false;
|
||||
bool concat = false;
|
||||
char * word = NULL;
|
||||
|
||||
if(!words.empty() && quoted)
|
||||
concat = true;
|
||||
|
||||
while(*line){
|
||||
if((*line == '#' || *line == ';') && !quoted){
|
||||
*bg = 0;
|
||||
if(strlen(start)){
|
||||
|
||||
if(concat){
|
||||
word = (char*)mempool->alloc(strlen(words.back())+strlen(start)+1);
|
||||
strcpy(word, words.back());
|
||||
strcat(word, start);
|
||||
words.pop_back();
|
||||
concat = false;
|
||||
} else {
|
||||
word = mempool->strdup(start);
|
||||
}
|
||||
words.push_back(word);
|
||||
}
|
||||
break;
|
||||
}
|
||||
if(*line == '=' && !quoted){
|
||||
*line = ' ';continue;
|
||||
}
|
||||
|
||||
// Allowing \" in there causes problems with directory paths
|
||||
// like "C:\TrinIty\"
|
||||
//if(*line == '\\' && (*(line+1) == '"' || *(line+1) == '\'')){
|
||||
if(*line == '\\' && (*(line+1) == '\'')) {
|
||||
*bg++ = *(line+1);
|
||||
line+=2; continue;
|
||||
}
|
||||
if(*line == '\\' && *(line+1) == 'n'){
|
||||
*bg++ = '\n';
|
||||
line+=2; continue;
|
||||
}
|
||||
if(*line == '\\' && *(line+1) == 'r'){
|
||||
*bg++ = '\r';
|
||||
line+=2; continue;
|
||||
}
|
||||
if(*line == '\\' && (*(line+1) == '\n' || *(line+1) == '\r')){
|
||||
*bg = 0;
|
||||
if(strlen(start)){
|
||||
|
||||
if(concat){
|
||||
word = (char*)mempool->alloc(strlen(words.back())+strlen(start)+1);
|
||||
strcpy(word, words.back());
|
||||
strcat(word, start);
|
||||
words.pop_back();
|
||||
concat = false;
|
||||
} else {
|
||||
word = mempool->strdup(start);
|
||||
}
|
||||
words.push_back(word);
|
||||
}
|
||||
multiline = true;
|
||||
break;
|
||||
}
|
||||
if(*line == '"' || *line == '\''){
|
||||
quoted = !quoted;
|
||||
++line; continue;
|
||||
}
|
||||
if(isspace((unsigned char)*line) && !quoted){
|
||||
*bg++ = 0;
|
||||
if(strlen(start)){
|
||||
|
||||
if(concat){
|
||||
word = (char*)mempool->alloc(strlen(words.back())+strlen(start)+1);
|
||||
strcpy(word, words.back());
|
||||
strcat(word, start);
|
||||
words.pop_back();
|
||||
concat = false;
|
||||
} else {
|
||||
word = mempool->strdup(start);
|
||||
}
|
||||
words.push_back(word);
|
||||
}
|
||||
start = bg;
|
||||
while(isspace((unsigned char)*++line)) {}
|
||||
|
||||
continue;
|
||||
}
|
||||
*bg++ = *line++;
|
||||
}
|
||||
|
||||
if(quoted && !multiline){
|
||||
error(curLine, fileName, "unterminated quote");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return multiline?1:0;
|
||||
}
|
||||
|
||||
int DOTCONFDocument::parseLine()
|
||||
{
|
||||
char * word = NULL;
|
||||
char * nodeName = NULL;
|
||||
char * nodeValue = NULL;
|
||||
DOTCONFDocumentNode * tagNode = NULL;
|
||||
bool newNode = false;
|
||||
|
||||
for (std::list<char*>::iterator i = words.begin(); i != words.end(); ++i) {
|
||||
word = *i;
|
||||
|
||||
if(*word == '<'){
|
||||
newNode = true;
|
||||
}
|
||||
|
||||
if(newNode){
|
||||
nodeValue = NULL;
|
||||
nodeName = NULL;
|
||||
newNode = false;
|
||||
}
|
||||
|
||||
size_t wordLen = strlen(word);
|
||||
if(word[wordLen-1] == '>'){
|
||||
word[wordLen-1] = 0;
|
||||
newNode = true;
|
||||
}
|
||||
|
||||
if(nodeName == NULL){
|
||||
nodeName = word;
|
||||
bool closed = true;
|
||||
if(*nodeName == '<'){
|
||||
if(*(nodeName+1) != '/'){
|
||||
++nodeName;
|
||||
closed = false;
|
||||
} else {
|
||||
nodeName+=2;
|
||||
std::list<DOTCONFDocumentNode*>::reverse_iterator itr=nodeTree.rbegin();
|
||||
for (; itr!=nodeTree.rend(); ++itr){
|
||||
if(!cmp_func(nodeName, (*itr)->name) && !(*itr)->closed){
|
||||
(*itr)->closed = true;
|
||||
curParent = (*itr)->parentNode;
|
||||
curPrev = *itr;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(itr==nodeTree.rend()){
|
||||
error(curLine, fileName, "not matched closing tag </%s>", nodeName);
|
||||
return -1;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
}
|
||||
tagNode = new DOTCONFDocumentNode;
|
||||
tagNode->name = strdup(nodeName);
|
||||
tagNode->document = this;
|
||||
tagNode->fileName = processedFiles.back();
|
||||
tagNode->lineNum = curLine;
|
||||
tagNode->closed = closed;
|
||||
if(!nodeTree.empty()){
|
||||
DOTCONFDocumentNode * prev = nodeTree.back();
|
||||
if(prev->closed){
|
||||
|
||||
curPrev->nextNode = tagNode;
|
||||
tagNode->previousNode = curPrev;
|
||||
tagNode->parentNode = curParent;
|
||||
|
||||
} else {
|
||||
prev->childNode = tagNode;
|
||||
tagNode->parentNode = prev;
|
||||
curParent = prev;
|
||||
}
|
||||
}
|
||||
nodeTree.push_back(tagNode);
|
||||
curPrev = tagNode;
|
||||
} else {
|
||||
nodeValue = word;
|
||||
tagNode->pushValue(nodeValue);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
int DOTCONFDocument::parseFile(DOTCONFDocumentNode * _parent)
|
||||
{
|
||||
char str[512];
|
||||
int ret = 0;
|
||||
curLine = 0;
|
||||
curParent = _parent;
|
||||
|
||||
quoted = false;
|
||||
size_t slen = 0;
|
||||
|
||||
while(fgets(str, 511, file)){
|
||||
++curLine;
|
||||
slen = strlen(str);
|
||||
if( slen >= 510 ){
|
||||
error(curLine, fileName, "warning: line too long");
|
||||
}
|
||||
if(str[slen-1] != '\n'){
|
||||
str[slen] = '\n';
|
||||
str[slen+1] = 0;
|
||||
}
|
||||
if((ret = cleanupLine(str)) == -1){
|
||||
break;
|
||||
}
|
||||
if(ret == 0){
|
||||
if(!words.empty()){
|
||||
ret = parseLine();
|
||||
mempool->free();
|
||||
words.clear();
|
||||
if(ret == -1){
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int DOTCONFDocument::checkConfig(const std::list<DOTCONFDocumentNode*>::iterator & from)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
DOTCONFDocumentNode * tagNode = NULL;
|
||||
int vi = 0;
|
||||
for (std::list<DOTCONFDocumentNode*>::iterator i = from; i != nodeTree.end(); ++i){
|
||||
tagNode = *i;
|
||||
if(!tagNode->closed){
|
||||
error(tagNode->lineNum, tagNode->fileName, "unclosed tag %s", tagNode->name);
|
||||
ret = -1;
|
||||
break;
|
||||
}
|
||||
vi = 0;
|
||||
while( vi < tagNode->valuesCount ){
|
||||
|
||||
if(strstr(tagNode->values[vi], "${") && strchr(tagNode->values[vi], '}') ){
|
||||
ret = macroSubstitute(tagNode, vi );
|
||||
mempool->free();
|
||||
if(ret == -1){
|
||||
break;
|
||||
}
|
||||
}
|
||||
++vi;
|
||||
}
|
||||
if(ret == -1){
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int DOTCONFDocument::setContent(const char * _fileName)
|
||||
{
|
||||
int ret = 0;
|
||||
char realpathBuf[PATH_MAX];
|
||||
|
||||
if(realpath(_fileName, realpathBuf) == NULL){
|
||||
error(0, NULL, "realpath(%s) failed: %s", _fileName, strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
fileName = strdup(realpathBuf);
|
||||
|
||||
processedFiles.push_back(strdup(realpathBuf));
|
||||
|
||||
if(( file = fopen(fileName, "r")) == NULL){
|
||||
error(0, NULL, "failed to open file '%s': %s", fileName, strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
// Try read utf8 header and skip it if exist
|
||||
uint32 utf8header = 0;
|
||||
fgets((char*)&utf8header, 4, file); // Try read header
|
||||
if (utf8header!=0x00BFBBEF) // If not exist
|
||||
fseek(file, 0, SEEK_SET); // Reset read position
|
||||
|
||||
ret = parseFile();
|
||||
|
||||
(void) fclose(file);
|
||||
|
||||
if(!ret){
|
||||
|
||||
if( (ret = checkConfig(nodeTree.begin())) == -1){
|
||||
return -1;
|
||||
}
|
||||
|
||||
std::list<DOTCONFDocumentNode*>::iterator from;
|
||||
DOTCONFDocumentNode * tagNode = NULL;
|
||||
int vi = 0;
|
||||
for (std::list<DOTCONFDocumentNode*>::iterator i = nodeTree.begin(); i!=nodeTree.end(); ++i){
|
||||
tagNode = *i;
|
||||
if(!cmp_func("DOTCONFPPIncludeFile", tagNode->name)){
|
||||
vi = 0;
|
||||
while( vi < tagNode->valuesCount ){
|
||||
if(access(tagNode->values[vi], R_OK) == -1){
|
||||
error(tagNode->lineNum, tagNode->fileName, "%s: %s", tagNode->values[vi], strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
if(realpath(tagNode->values[vi], realpathBuf) == NULL){
|
||||
error(tagNode->lineNum, tagNode->fileName, "realpath(%s) failed: %s", tagNode->values[vi], strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
bool processed = false;
|
||||
for (std::list<char*>::const_iterator itInode = processedFiles.begin(); itInode != processedFiles.end(); ++itInode){
|
||||
if(!strcmp(*itInode, realpathBuf)){
|
||||
processed = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(processed){
|
||||
break;
|
||||
}
|
||||
|
||||
processedFiles.push_back(strdup(realpathBuf));
|
||||
|
||||
file = fopen(tagNode->values[vi], "r");
|
||||
if(file == NULL){
|
||||
error(tagNode->lineNum, fileName, "failed to open file '%s': %s", tagNode->values[vi], strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
fileName = strdup(realpathBuf);
|
||||
from = nodeTree.end(); --from;
|
||||
|
||||
ret = parseFile();
|
||||
(void) fclose(file);
|
||||
if(ret == -1)
|
||||
return -1;
|
||||
if(checkConfig(++from) == -1){
|
||||
return -1;
|
||||
}
|
||||
++vi;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(!requiredOptions.empty())
|
||||
ret = checkRequiredOptions();
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int DOTCONFDocument::checkRequiredOptions()
|
||||
{
|
||||
for (std::list<char*>::const_iterator ci = requiredOptions.begin(); ci != requiredOptions.end(); ++ci){
|
||||
bool matched = false;
|
||||
for (std::list<DOTCONFDocumentNode*>::iterator i = nodeTree.begin(); i!=nodeTree.end(); ++i){
|
||||
if(!cmp_func((*i)->name, *ci)){
|
||||
matched = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(!matched){
|
||||
error(0, NULL, "required option '%s' not specified", *ci);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void DOTCONFDocument::error(int lineNum, const char * fileName_, const char * fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
|
||||
size_t len = (lineNum!=0?strlen(fileName_):0) + strlen(fmt) + 50;
|
||||
char * buf = (char*)mempool->alloc(len);
|
||||
|
||||
if(lineNum)
|
||||
(void) snprintf(buf, len, "DOTCONF++: file '%s', line %d: %s\n", fileName_, lineNum, fmt);
|
||||
else
|
||||
(void) snprintf(buf, len, "DOTCONF++: %s\n", fmt);
|
||||
|
||||
(void) vfprintf(stderr, buf, args);
|
||||
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
char * DOTCONFDocument::getSubstitution(char * macro, int lineNum)
|
||||
{
|
||||
char * buf = NULL;
|
||||
char * variable = macro+2;
|
||||
|
||||
char * endBr = strchr(macro, '}');
|
||||
|
||||
if(!endBr){
|
||||
error(lineNum, fileName, "unterminated '{'");
|
||||
return NULL;
|
||||
}
|
||||
*endBr = 0;
|
||||
|
||||
char * defaultValue = strchr(variable, ':');
|
||||
|
||||
if(defaultValue){
|
||||
*defaultValue++ = 0;
|
||||
if(*defaultValue != '-'){
|
||||
error(lineNum, fileName, "incorrect macro substitution syntax");
|
||||
return NULL;
|
||||
}
|
||||
++defaultValue;
|
||||
if(*defaultValue == '"' || *defaultValue == '\''){
|
||||
++defaultValue;
|
||||
defaultValue[strlen(defaultValue)-1] = 0;
|
||||
}
|
||||
} else {
|
||||
defaultValue = NULL;
|
||||
}
|
||||
|
||||
char * subs = getenv(variable);
|
||||
if( subs ){
|
||||
buf = mempool->strdup(subs);
|
||||
} else {
|
||||
std::list<DOTCONFDocumentNode*>::iterator i = nodeTree.begin();
|
||||
DOTCONFDocumentNode * tagNode = NULL;
|
||||
for (; i!=nodeTree.end(); i++){
|
||||
tagNode = *i;
|
||||
if(!cmp_func(tagNode->name, variable)){
|
||||
if(tagNode->valuesCount != 0){
|
||||
buf = mempool->strdup(tagNode->values[0]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if( i == nodeTree.end() ){
|
||||
if( defaultValue ){
|
||||
buf = mempool->strdup(defaultValue);
|
||||
} else {
|
||||
error(lineNum, fileName, "substitution not found and default value not given");
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
return buf;
|
||||
}
|
||||
|
||||
int DOTCONFDocument::macroSubstitute(DOTCONFDocumentNode * tagNode, int valueIndex)
|
||||
{
|
||||
int ret = 0;
|
||||
char * macro = tagNode->values[valueIndex];
|
||||
size_t valueLen = strlen(tagNode->values[valueIndex])+1;
|
||||
char * value = (char*)mempool->alloc(valueLen);
|
||||
char * v = value;
|
||||
char * subs = NULL;
|
||||
|
||||
while(*macro){
|
||||
if(*macro == '$' && *(macro+1) == '{'){
|
||||
char * m = strchr(macro, '}');
|
||||
subs = getSubstitution(macro, tagNode->lineNum);
|
||||
if(subs == NULL){
|
||||
ret = -1;
|
||||
break;
|
||||
}
|
||||
macro = m + 1;
|
||||
*v = 0;
|
||||
v = (char*)mempool->alloc(strlen(value)+strlen(subs)+valueLen);
|
||||
strcpy(v, value);
|
||||
value = strcat(v, subs);
|
||||
v = value + strlen(value);
|
||||
continue;
|
||||
}
|
||||
*v++ = *macro++;
|
||||
}
|
||||
*v = 0;
|
||||
|
||||
free(tagNode->values[valueIndex]);
|
||||
tagNode->values[valueIndex] = strdup(value);
|
||||
return ret;
|
||||
}
|
||||
|
||||
const DOTCONFDocumentNode * DOTCONFDocument::getFirstNode() const
|
||||
{
|
||||
if ( !nodeTree.empty() ) {
|
||||
return *nodeTree.begin();
|
||||
} else {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
const DOTCONFDocumentNode * DOTCONFDocument::findNode(const char * nodeName, const DOTCONFDocumentNode * parentNode, const DOTCONFDocumentNode * startNode) const
|
||||
{
|
||||
|
||||
std::list<DOTCONFDocumentNode*>::const_iterator i = nodeTree.begin();
|
||||
|
||||
if(startNode == NULL)
|
||||
startNode = parentNode;
|
||||
|
||||
if(startNode != NULL){
|
||||
while( i != nodeTree.end() && (*i) != startNode ){
|
||||
++i;
|
||||
}
|
||||
if( i != nodeTree.end() ) ++i;
|
||||
}
|
||||
|
||||
for (; i!=nodeTree.end(); ++i){
|
||||
|
||||
if((*i)->parentNode != parentNode){
|
||||
continue;
|
||||
}
|
||||
if(!cmp_func(nodeName, (*i)->name)){
|
||||
return *i;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void DOTCONFDocument::setRequiredOptionNames(const char ** requiredOptionNames)
|
||||
{
|
||||
while(*requiredOptionNames){
|
||||
requiredOptions.push_back(strdup( *requiredOptionNames ));
|
||||
++requiredOptionNames;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,97 @@
|
||||
|
||||
|
||||
#ifndef DOTCONFPP_H
|
||||
#define DOTCONFPP_H
|
||||
|
||||
#include <list>
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include "mempool.h"
|
||||
|
||||
class DOTCONFDocument;
|
||||
|
||||
class DOTCONFDocumentNode
|
||||
{
|
||||
friend class DOTCONFDocument;
|
||||
private:
|
||||
DOTCONFDocumentNode * previousNode;
|
||||
DOTCONFDocumentNode * nextNode;
|
||||
DOTCONFDocumentNode * parentNode;
|
||||
DOTCONFDocumentNode * childNode;
|
||||
char ** values;
|
||||
int valuesCount;
|
||||
char * name;
|
||||
const DOTCONFDocument * document;
|
||||
int lineNum;
|
||||
char * fileName;
|
||||
bool closed;
|
||||
|
||||
void pushValue(char * _value);
|
||||
|
||||
public:
|
||||
DOTCONFDocumentNode();
|
||||
~DOTCONFDocumentNode();
|
||||
|
||||
const char * getConfigurationFileName()const { return fileName; }
|
||||
int getConfigurationLineNumber() const { return lineNum; }
|
||||
|
||||
const DOTCONFDocumentNode * getNextNode() const { return nextNode; }
|
||||
const DOTCONFDocumentNode * getPreviuosNode() const { return previousNode; }
|
||||
const DOTCONFDocumentNode * getParentNode() const { return parentNode; }
|
||||
const DOTCONFDocumentNode * getChildNode() const { return childNode; }
|
||||
const char* getValue(int index = 0) const;
|
||||
const char * getName() const { return name; }
|
||||
const DOTCONFDocument * getDocument() const { return document; }
|
||||
};
|
||||
|
||||
class DOTCONFDocument
|
||||
{
|
||||
public:
|
||||
enum CaseSensitive { CASESENSETIVE, CASEINSENSETIVE };
|
||||
protected:
|
||||
AsyncDNSMemPool * mempool;
|
||||
private:
|
||||
DOTCONFDocumentNode * curParent;
|
||||
DOTCONFDocumentNode * curPrev;
|
||||
int curLine;
|
||||
bool quoted;
|
||||
std::list<DOTCONFDocumentNode*> nodeTree;
|
||||
std::list<char*> requiredOptions;
|
||||
std::list<char*> processedFiles;
|
||||
FILE * file;
|
||||
char * fileName;
|
||||
std::list<char*> words;
|
||||
int (*cmp_func)(const char *, const char *);
|
||||
|
||||
int checkRequiredOptions();
|
||||
int parseLine();
|
||||
int parseFile(DOTCONFDocumentNode * _parent = NULL);
|
||||
int checkConfig(const std::list<DOTCONFDocumentNode*>::iterator & from);
|
||||
int cleanupLine(char * line);
|
||||
char * getSubstitution(char * macro, int lineNum);
|
||||
int macroSubstitute(DOTCONFDocumentNode * tagNode, int valueIndex);
|
||||
|
||||
protected:
|
||||
virtual void error(int lineNum, const char * fileName, const char * fmt, ...) ATTR_PRINTF(4,5);
|
||||
|
||||
public:
|
||||
DOTCONFDocument(CaseSensitive caseSensitivity = CASESENSETIVE);
|
||||
virtual ~DOTCONFDocument();
|
||||
|
||||
int setContent(const char * _fileName);
|
||||
|
||||
void setRequiredOptionNames(const char ** requiredOptionNames);
|
||||
const DOTCONFDocumentNode * getFirstNode() const;
|
||||
const DOTCONFDocumentNode * findNode(const char * nodeName, const DOTCONFDocumentNode * parentNode = NULL, const DOTCONFDocumentNode * startNode = NULL) const;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,100 @@
|
||||
|
||||
|
||||
#include "mempool.h"
|
||||
|
||||
AsyncDNSMemPool::PoolChunk::PoolChunk(size_t _size):
|
||||
pool(NULL), pos(0), size(_size)
|
||||
{
|
||||
pool = ::malloc(size);
|
||||
}
|
||||
|
||||
AsyncDNSMemPool::PoolChunk::~PoolChunk()
|
||||
{
|
||||
::free(pool);
|
||||
}
|
||||
|
||||
AsyncDNSMemPool::AsyncDNSMemPool(size_t _defaultSize):
|
||||
chunks(NULL), chunksCount(0), defaultSize(_defaultSize),
|
||||
poolUsage(0), poolUsageCounter(0)
|
||||
{
|
||||
}
|
||||
|
||||
AsyncDNSMemPool::~AsyncDNSMemPool()
|
||||
{
|
||||
for (size_t i = 0; i<chunksCount; ++i){
|
||||
delete chunks[i];
|
||||
}
|
||||
::free(chunks);
|
||||
}
|
||||
|
||||
int AsyncDNSMemPool::initialize()
|
||||
{
|
||||
chunksCount = 1;
|
||||
chunks = (PoolChunk**)::malloc(sizeof(PoolChunk*));
|
||||
if(chunks == NULL)
|
||||
return -1;
|
||||
|
||||
chunks[chunksCount-1] = new PoolChunk(defaultSize);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void AsyncDNSMemPool::addNewChunk(size_t size)
|
||||
{
|
||||
++chunksCount;
|
||||
chunks = (PoolChunk**)::realloc(chunks, chunksCount*sizeof(PoolChunk*));
|
||||
if(size <= defaultSize)
|
||||
chunks[chunksCount-1] = new PoolChunk(defaultSize);
|
||||
else
|
||||
chunks[chunksCount-1] = new PoolChunk(size);
|
||||
}
|
||||
|
||||
void * AsyncDNSMemPool::alloc(size_t size)
|
||||
{
|
||||
PoolChunk * chunk = NULL;
|
||||
for (size_t i = 0; i<chunksCount; ++i){
|
||||
chunk = chunks[i];
|
||||
if((chunk->size - chunk->pos) >= size){
|
||||
chunk->pos += size;
|
||||
return ((char*)chunk->pool) + chunk->pos - size;
|
||||
}
|
||||
}
|
||||
addNewChunk(size);
|
||||
chunks[chunksCount-1]->pos = size;
|
||||
return chunks[chunksCount-1]->pool;
|
||||
}
|
||||
|
||||
void AsyncDNSMemPool::free()
|
||||
{
|
||||
size_t pu = 0;
|
||||
size_t psz = 0;
|
||||
++poolUsageCounter;
|
||||
|
||||
for (size_t i = 0; i<chunksCount; ++i){
|
||||
pu += chunks[i]->pos;
|
||||
psz += chunks[i]->size;
|
||||
chunks[i]->pos = 0;
|
||||
}
|
||||
poolUsage=(poolUsage>pu)?poolUsage:pu;
|
||||
|
||||
if(poolUsageCounter >= 10 && chunksCount > 1){
|
||||
psz -= chunks[chunksCount-1]->size;
|
||||
if(poolUsage < psz){
|
||||
--chunksCount;
|
||||
delete chunks[chunksCount];
|
||||
}
|
||||
poolUsage = 0;
|
||||
poolUsageCounter = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void * AsyncDNSMemPool::calloc(size_t size)
|
||||
{
|
||||
return ::memset(this->alloc(size), 0, size);
|
||||
}
|
||||
|
||||
char * AsyncDNSMemPool::strdup(const char *str)
|
||||
{
|
||||
return ::strcpy((char*)this->alloc(strlen(str)+1), str);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,46 @@
|
||||
|
||||
|
||||
#ifndef ASYNC_DNS_MEMPOOL_H
|
||||
#define ASYNC_DNS_MEMPOOL_H
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#undef free
|
||||
#undef calloc
|
||||
#undef strdup
|
||||
|
||||
class AsyncDNSMemPool
|
||||
{
|
||||
private:
|
||||
struct PoolChunk {
|
||||
void * pool;
|
||||
size_t pos;
|
||||
size_t size;
|
||||
|
||||
PoolChunk(size_t _size);
|
||||
~PoolChunk();
|
||||
};
|
||||
PoolChunk ** chunks;
|
||||
size_t chunksCount;
|
||||
size_t defaultSize;
|
||||
|
||||
size_t poolUsage;
|
||||
size_t poolUsageCounter;
|
||||
|
||||
void addNewChunk(size_t size);
|
||||
|
||||
public:
|
||||
AsyncDNSMemPool(size_t _defaultSize = 4096);
|
||||
virtual ~AsyncDNSMemPool();
|
||||
|
||||
int initialize();
|
||||
void free();
|
||||
void * alloc(size_t size);
|
||||
void * calloc(size_t size);
|
||||
char * strdup(const char *str);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
SET(trinitydatabase_STAT_SRCS
|
||||
DBCFileLoader.cpp
|
||||
DBCFileLoader.h
|
||||
DBCStore.h
|
||||
Database.cpp
|
||||
Database.h
|
||||
DatabaseEnv.h
|
||||
DatabaseImpl.h
|
||||
Field.cpp
|
||||
Field.h
|
||||
QueryResult.cpp
|
||||
QueryResult.h
|
||||
SQLStorage.cpp
|
||||
SQLStorage.h
|
||||
SqlDelayThread.cpp
|
||||
SqlDelayThread.h
|
||||
SqlOperations.cpp
|
||||
SqlOperations.h
|
||||
)
|
||||
|
||||
include_directories(
|
||||
${ACE_INCLUDE_DIR}
|
||||
${CMAKE_BINARY_DIR}
|
||||
${CMAKE_SOURCE_DIR}/src/shared
|
||||
${CMAKE_SOURCE_DIR}/src/shared/Database
|
||||
${CMAKE_SOURCE_DIR}/src/framework
|
||||
${MYSQL_INCLUDE_DIR}
|
||||
)
|
||||
|
||||
add_library(trinitydatabase STATIC ${trinitydatabase_STAT_SRCS})
|
||||
@@ -0,0 +1,270 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
|
||||
*
|
||||
* Copyright (C) 2008-2010 Trinity <http://www.trinitycore.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; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public 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 <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "DBCFileLoader.h"
|
||||
|
||||
DBCFileLoader::DBCFileLoader()
|
||||
{
|
||||
data = NULL;
|
||||
fieldsOffset = NULL;
|
||||
}
|
||||
|
||||
bool DBCFileLoader::Load(const char *filename, const char *fmt)
|
||||
{
|
||||
uint32 header;
|
||||
if (data)
|
||||
{
|
||||
delete [] data;
|
||||
data = NULL;
|
||||
}
|
||||
|
||||
FILE * f = fopen(filename,"rb");
|
||||
if (!f)
|
||||
return false;
|
||||
|
||||
if (fread(&header,4,1,f)!=1) // Number of records
|
||||
return false;
|
||||
|
||||
EndianConvert(header);
|
||||
|
||||
if (header!=0x43424457)
|
||||
return false; //'WDBC'
|
||||
|
||||
if (fread(&recordCount,4,1,f)!=1) // Number of records
|
||||
return false;
|
||||
|
||||
EndianConvert(recordCount);
|
||||
|
||||
if (fread(&fieldCount,4,1,f)!=1) // Number of fields
|
||||
return false;
|
||||
|
||||
EndianConvert(fieldCount);
|
||||
|
||||
if (fread(&recordSize,4,1,f)!=1) // Size of a record
|
||||
return false;
|
||||
|
||||
EndianConvert(recordSize);
|
||||
|
||||
if (fread(&stringSize,4,1,f)!=1) // String size
|
||||
return false;
|
||||
|
||||
EndianConvert(stringSize);
|
||||
|
||||
fieldsOffset = new uint32[fieldCount];
|
||||
fieldsOffset[0] = 0;
|
||||
for (uint32 i = 1; i < fieldCount; i++)
|
||||
{
|
||||
fieldsOffset[i] = fieldsOffset[i - 1];
|
||||
if (fmt[i - 1] == 'b' || fmt[i - 1] == 'X') // byte fields
|
||||
fieldsOffset[i] += 1;
|
||||
else // 4 byte fields (int32/float/strings)
|
||||
fieldsOffset[i] += 4;
|
||||
}
|
||||
|
||||
data = new unsigned char[recordSize*recordCount+stringSize];
|
||||
stringTable = data + recordSize*recordCount;
|
||||
|
||||
if (fread(data,recordSize*recordCount+stringSize,1,f)!=1)
|
||||
return false;
|
||||
|
||||
fclose(f);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
DBCFileLoader::~DBCFileLoader()
|
||||
{
|
||||
if (data)
|
||||
delete [] data;
|
||||
|
||||
if (fieldsOffset)
|
||||
delete [] fieldsOffset;
|
||||
}
|
||||
|
||||
DBCFileLoader::Record DBCFileLoader::getRecord(size_t id)
|
||||
{
|
||||
assert(data);
|
||||
return Record(*this, data + id*recordSize);
|
||||
}
|
||||
|
||||
uint32 DBCFileLoader::GetFormatRecordSize(const char * format,int32* index_pos)
|
||||
{
|
||||
uint32 recordsize = 0;
|
||||
int32 i = -1;
|
||||
for (uint32 x=0; format[x]; ++x)
|
||||
{
|
||||
switch(format[x])
|
||||
{
|
||||
case FT_FLOAT:
|
||||
case FT_INT:
|
||||
recordsize+=4;
|
||||
break;
|
||||
case FT_STRING:
|
||||
recordsize+=sizeof(char*);
|
||||
break;
|
||||
case FT_SORT:
|
||||
i=x;
|
||||
break;
|
||||
case FT_IND:
|
||||
i=x;
|
||||
recordsize+=4;
|
||||
break;
|
||||
case FT_BYTE:
|
||||
recordsize += 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (index_pos)
|
||||
*index_pos = i;
|
||||
|
||||
return recordsize;
|
||||
}
|
||||
|
||||
char* DBCFileLoader::AutoProduceData(const char* format, uint32& records, char**& indexTable, uint32 sqlRecordCount, uint32 sqlHighestIndex, char *& sqlDataTable)
|
||||
{
|
||||
/*
|
||||
format STRING, NA, FLOAT,NA,INT <=>
|
||||
struct{
|
||||
char* field0,
|
||||
float field1,
|
||||
int field2
|
||||
}entry;
|
||||
|
||||
this func will generate entry[rows] data;
|
||||
*/
|
||||
|
||||
typedef char * ptr;
|
||||
if (strlen(format)!=fieldCount)
|
||||
return NULL;
|
||||
|
||||
//get struct size and index pos
|
||||
int32 i;
|
||||
uint32 recordsize=GetFormatRecordSize(format,&i);
|
||||
|
||||
if (i>=0)
|
||||
{
|
||||
uint32 maxi=0;
|
||||
//find max index
|
||||
for (uint32 y=0; y<recordCount; y++)
|
||||
{
|
||||
uint32 ind=getRecord(y).getUInt (i);
|
||||
if(ind>maxi)maxi=ind;
|
||||
}
|
||||
|
||||
// If higher index avalible from sql - use it instead of dbcs
|
||||
if (sqlHighestIndex > maxi)
|
||||
maxi = sqlHighestIndex;
|
||||
|
||||
++maxi;
|
||||
records=maxi;
|
||||
indexTable=new ptr[maxi];
|
||||
memset(indexTable,0,maxi*sizeof(ptr));
|
||||
}
|
||||
else
|
||||
{
|
||||
records = recordCount + sqlRecordCount;
|
||||
indexTable = new ptr[recordCount+ sqlRecordCount];
|
||||
}
|
||||
|
||||
char* dataTable= new char[(recordCount + sqlRecordCount)*recordsize];
|
||||
|
||||
uint32 offset=0;
|
||||
|
||||
for (uint32 y =0; y<recordCount; ++y)
|
||||
{
|
||||
if(i>=0)
|
||||
indexTable[getRecord(y).getUInt(i)]=&dataTable[offset];
|
||||
else
|
||||
indexTable[y]=&dataTable[offset];
|
||||
|
||||
for (uint32 x=0; x<fieldCount; x++)
|
||||
{
|
||||
switch(format[x])
|
||||
{
|
||||
case FT_FLOAT:
|
||||
*((float*)(&dataTable[offset]))=getRecord(y).getFloat(x);
|
||||
offset+=4;
|
||||
break;
|
||||
case FT_IND:
|
||||
case FT_INT:
|
||||
*((uint32*)(&dataTable[offset]))=getRecord(y).getUInt(x);
|
||||
offset+=4;
|
||||
break;
|
||||
case FT_BYTE:
|
||||
*((uint8*)(&dataTable[offset]))=getRecord(y).getUInt8(x);
|
||||
offset+=1;
|
||||
break;
|
||||
case FT_STRING:
|
||||
*((char**)(&dataTable[offset]))=NULL; // will be replaces non-empty or "" strings in AutoProduceStrings
|
||||
offset+=sizeof(char*);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sqlDataTable = dataTable + offset;
|
||||
|
||||
return dataTable;
|
||||
}
|
||||
|
||||
char* DBCFileLoader::AutoProduceStrings(const char* format, char* dataTable)
|
||||
{
|
||||
if (strlen(format)!=fieldCount)
|
||||
return NULL;
|
||||
|
||||
char* stringPool= new char[stringSize];
|
||||
memcpy(stringPool,stringTable,stringSize);
|
||||
|
||||
uint32 offset=0;
|
||||
|
||||
for (uint32 y =0; y<recordCount; y++)
|
||||
{
|
||||
for (uint32 x=0; x<fieldCount; x++)
|
||||
switch(format[x])
|
||||
{
|
||||
case FT_FLOAT:
|
||||
case FT_IND:
|
||||
case FT_INT:
|
||||
offset+=4;
|
||||
break;
|
||||
case FT_BYTE:
|
||||
offset+=1;
|
||||
break;
|
||||
case FT_STRING:
|
||||
// fill only not filled entries
|
||||
char** slot = (char**)(&dataTable[offset]);
|
||||
if(!*slot || !**slot)
|
||||
{
|
||||
const char * st = getRecord(y).getString(x);
|
||||
*slot=stringPool+(st-(const char*)stringTable);
|
||||
}
|
||||
offset+=sizeof(char*);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return stringPool;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,110 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public 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 DBC_FILE_LOADER_H
|
||||
#define DBC_FILE_LOADER_H
|
||||
#include "Platform/Define.h"
|
||||
#include "Utilities/ByteConverter.h"
|
||||
#include <cassert>
|
||||
|
||||
enum
|
||||
{
|
||||
FT_NA='x', //not used or unknown, 4 byte size
|
||||
FT_NA_BYTE='X', //not used or unknown, byte
|
||||
FT_STRING='s', //char*
|
||||
FT_FLOAT='f', //float
|
||||
FT_INT='i', //uint32
|
||||
FT_BYTE='b', //uint8
|
||||
FT_SORT='d', //sorted by this field, field is not included
|
||||
FT_IND='n', //the same,but parsed to data
|
||||
FT_LOGIC='l', //Logical (boolean)
|
||||
FT_SQL_PRESENT='p', //Used in sql format to mark column present in sql dbc
|
||||
FT_SQL_ABSENT='a' //Used in sql format to mark column absent in sql dbc
|
||||
};
|
||||
|
||||
class DBCFileLoader
|
||||
{
|
||||
public:
|
||||
DBCFileLoader();
|
||||
~DBCFileLoader();
|
||||
|
||||
bool Load(const char *filename, const char *fmt);
|
||||
|
||||
class Record
|
||||
{
|
||||
public:
|
||||
float getFloat(size_t field) const
|
||||
{
|
||||
assert(field < file.fieldCount);
|
||||
float val = *reinterpret_cast<float*>(offset+file.GetOffset(field));
|
||||
EndianConvert(val);
|
||||
return val;
|
||||
}
|
||||
uint32 getUInt(size_t field) const
|
||||
{
|
||||
assert(field < file.fieldCount);
|
||||
uint32 val = *reinterpret_cast<uint32*>(offset+file.GetOffset(field));
|
||||
EndianConvert(val);
|
||||
return val;
|
||||
}
|
||||
uint8 getUInt8(size_t field) const
|
||||
{
|
||||
assert(field < file.fieldCount);
|
||||
return *reinterpret_cast<uint8*>(offset+file.GetOffset(field));
|
||||
}
|
||||
|
||||
const char *getString(size_t field) const
|
||||
{
|
||||
assert(field < file.fieldCount);
|
||||
size_t stringOffset = getUInt(field);
|
||||
assert(stringOffset < file.stringSize);
|
||||
return reinterpret_cast<char*>(file.stringTable + stringOffset);
|
||||
}
|
||||
|
||||
private:
|
||||
Record(DBCFileLoader &file_, unsigned char *offset_): offset(offset_), file(file_) {}
|
||||
unsigned char *offset;
|
||||
DBCFileLoader &file;
|
||||
|
||||
friend class DBCFileLoader;
|
||||
|
||||
};
|
||||
|
||||
// Get record by id
|
||||
Record getRecord(size_t id);
|
||||
/// Get begin iterator over records
|
||||
|
||||
uint32 GetNumRows() const { return recordCount; }
|
||||
uint32 GetRowSize() const { return recordSize; }
|
||||
uint32 GetCols() const { return fieldCount; }
|
||||
uint32 GetOffset(size_t id) const { return (fieldsOffset != NULL && id < fieldCount) ? fieldsOffset[id] : 0; }
|
||||
bool IsLoaded() { return data != NULL; }
|
||||
char* AutoProduceData(const char* fmt, uint32& count, char**& indexTable, uint32 sqlRecordCount, uint32 sqlHighestIndex, char *& sqlDataTable);
|
||||
char* AutoProduceStrings(const char* fmt, char* dataTable);
|
||||
static uint32 GetFormatRecordSize(const char * format, int32 * index_pos = NULL);
|
||||
private:
|
||||
|
||||
uint32 recordSize;
|
||||
uint32 recordCount;
|
||||
uint32 fieldCount;
|
||||
uint32 stringSize;
|
||||
uint32 *fieldsOffset;
|
||||
unsigned char *data;
|
||||
unsigned char *stringTable;
|
||||
};
|
||||
#endif
|
||||
@@ -0,0 +1,265 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public 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 DBCSTORE_H
|
||||
#define DBCSTORE_H
|
||||
|
||||
#include "DBCFileLoader.h"
|
||||
#include "Log.h"
|
||||
|
||||
struct SqlDbc
|
||||
{
|
||||
const std::string * formatString;
|
||||
const std::string * indexName;
|
||||
std::string sqlTableName;
|
||||
int32 indexPos;
|
||||
int32 sqlIndexPos;
|
||||
SqlDbc(const std::string * _filename, const std::string * _format, const std::string * _idname, const char * fmt)
|
||||
:formatString(_format),sqlIndexPos(0), indexName (_idname)
|
||||
{
|
||||
// Convert dbc file name to sql table name
|
||||
sqlTableName = *_filename;
|
||||
for (uint32 i = 0; i< sqlTableName.size(); ++i)
|
||||
{
|
||||
if (isalpha(sqlTableName[i]))
|
||||
sqlTableName[i] = tolower(sqlTableName[i]);
|
||||
else if (sqlTableName[i] == '.')
|
||||
sqlTableName[i] = '_';
|
||||
}
|
||||
|
||||
// Get sql index position
|
||||
DBCFileLoader::GetFormatRecordSize(fmt, &indexPos);
|
||||
if (indexPos>=0)
|
||||
{
|
||||
for (int32 x=0; x < formatString->size(); x++)
|
||||
{
|
||||
// Count only fields present in sql
|
||||
if ((*formatString)[x] == FT_SQL_PRESENT)
|
||||
{
|
||||
if (x == indexPos)
|
||||
break;
|
||||
++sqlIndexPos;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
template<class T>
|
||||
class DBCStorage
|
||||
{
|
||||
typedef std::list<char*> StringPoolList;
|
||||
public:
|
||||
explicit DBCStorage(const char *f) : nCount(0), fieldCount(0), fmt(f), indexTable(NULL), m_dataTable(NULL) { }
|
||||
~DBCStorage() { Clear(); }
|
||||
|
||||
T const* LookupEntry(uint32 id) const { return (id>=nCount)?NULL:indexTable[id]; }
|
||||
uint32 GetNumRows() const { return nCount; }
|
||||
char const* GetFormat() const { return fmt; }
|
||||
uint32 GetFieldCount() const { return fieldCount; }
|
||||
|
||||
bool Load(char const* fn, SqlDbc * sql)
|
||||
{
|
||||
DBCFileLoader dbc;
|
||||
// Check if load was sucessful, only then continue
|
||||
if (!dbc.Load(fn, fmt))
|
||||
return false;
|
||||
|
||||
uint32 sqlRecordCount = 0;
|
||||
uint32 sqlHighestIndex = 0;
|
||||
Field *fields = NULL;
|
||||
QueryResult_AutoPtr result = QueryResult_AutoPtr(NULL);
|
||||
// Load data from sql
|
||||
if (sql)
|
||||
{
|
||||
std::string query = "SELECT * FROM " + sql->sqlTableName;
|
||||
if (sql->indexPos >= 0)
|
||||
query +=" ORDER BY + " + *sql->indexName + " DESC";
|
||||
query += ";";
|
||||
|
||||
result = WorldDatabase.Query(query.c_str());
|
||||
if (result)
|
||||
{
|
||||
sqlRecordCount = result->GetRowCount();
|
||||
if (sql->indexPos >= 0)
|
||||
{
|
||||
fields = result->Fetch();
|
||||
sqlHighestIndex = fields[sql->sqlIndexPos].GetUInt32();
|
||||
}
|
||||
// Check if sql index pos is valid
|
||||
if (int32(result->GetFieldCount()-1) < sql->sqlIndexPos)
|
||||
{
|
||||
sLog.outError("Invalid index pos for dbc:'%s'", sql->sqlTableName.c_str());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
char * sqlDataTable;
|
||||
fieldCount = dbc.GetCols();
|
||||
m_dataTable = (T*)dbc.AutoProduceData(fmt,nCount,(char**&)indexTable, sqlRecordCount, sqlHighestIndex, sqlDataTable);
|
||||
|
||||
m_stringPoolList.push_back(dbc.AutoProduceStrings(fmt,(char*)m_dataTable));
|
||||
|
||||
// Insert sql data into arrays
|
||||
if (result)
|
||||
{
|
||||
if (indexTable)
|
||||
{
|
||||
uint32 offset = 0;
|
||||
uint32 rowIndex = dbc.GetNumRows();
|
||||
do
|
||||
{
|
||||
if (!fields)
|
||||
fields = result->Fetch();
|
||||
|
||||
if(sql->indexPos >= 0)
|
||||
{
|
||||
uint32 id = fields[sql->sqlIndexPos].GetUInt32();
|
||||
if (indexTable[id])
|
||||
{
|
||||
sLog.outError("Index %d already exists in dbc:'%s'", id, sql->sqlTableName.c_str());
|
||||
return false;
|
||||
}
|
||||
indexTable[id]=(T*)&sqlDataTable[offset];
|
||||
}
|
||||
else
|
||||
indexTable[rowIndex]=(T*)&sqlDataTable[offset];
|
||||
uint32 columnNumber = 0;
|
||||
uint32 sqlColumnNumber = 0;
|
||||
|
||||
for (; columnNumber < sql->formatString->size(); ++columnNumber)
|
||||
{
|
||||
if ((*sql->formatString)[columnNumber] == FT_SQL_ABSENT)
|
||||
{
|
||||
switch(fmt[columnNumber])
|
||||
{
|
||||
case FT_FLOAT:
|
||||
*((float*)(&sqlDataTable[offset]))= 0.0f;
|
||||
offset+=4;
|
||||
break;
|
||||
case FT_IND:
|
||||
case FT_INT:
|
||||
*((uint32*)(&sqlDataTable[offset]))=uint32(0);
|
||||
offset+=4;
|
||||
break;
|
||||
case FT_BYTE:
|
||||
*((uint8*)(&sqlDataTable[offset]))=uint8(0);
|
||||
offset+=1;
|
||||
break;
|
||||
case FT_STRING:
|
||||
// Beginning of the pool - empty string
|
||||
*((char**)(&sqlDataTable[offset]))=m_stringPoolList.back();
|
||||
offset+=sizeof(char*);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if ((*sql->formatString)[columnNumber] == FT_SQL_PRESENT)
|
||||
{
|
||||
bool validSqlColumn = true;
|
||||
switch(fmt[columnNumber])
|
||||
{
|
||||
case FT_FLOAT:
|
||||
*((float*)(&sqlDataTable[offset]))=fields[sqlColumnNumber].GetFloat();
|
||||
offset+=4;
|
||||
break;
|
||||
case FT_IND:
|
||||
case FT_INT:
|
||||
*((uint32*)(&sqlDataTable[offset]))=fields[sqlColumnNumber].GetUInt32();
|
||||
offset+=4;
|
||||
break;
|
||||
case FT_BYTE:
|
||||
*((uint8*)(&sqlDataTable[offset]))=fields[sqlColumnNumber].GetUInt8();
|
||||
offset+=1;
|
||||
break;
|
||||
case FT_STRING:
|
||||
sLog.outError("Unsupported data type in table '%s' at char %d", sql->sqlTableName.c_str(), columnNumber);
|
||||
return false;
|
||||
case FT_SORT:
|
||||
break;
|
||||
default:
|
||||
validSqlColumn = false;
|
||||
}
|
||||
if (validSqlColumn && (columnNumber != (sql->formatString->size()-1)))
|
||||
sqlColumnNumber++;
|
||||
}
|
||||
else
|
||||
{
|
||||
sLog.outError("Incorrect sql format string '%s' at char %d", sql->sqlTableName.c_str(), columnNumber);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (sqlColumnNumber != (result->GetFieldCount()-1))
|
||||
{
|
||||
sLog.outError("SQL and DBC format strings are not matching for table: '%s'", sql->sqlTableName.c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
fields = NULL;
|
||||
++rowIndex;
|
||||
}while (result->NextRow());
|
||||
}
|
||||
}
|
||||
|
||||
// error in dbc file at loading if NULL
|
||||
return indexTable!=NULL;
|
||||
}
|
||||
|
||||
bool LoadStringsFrom(char const* fn)
|
||||
{
|
||||
// DBC must be already loaded using Load
|
||||
if(!indexTable)
|
||||
return false;
|
||||
|
||||
DBCFileLoader dbc;
|
||||
// Check if load was successful, only then continue
|
||||
if(!dbc.Load(fn, fmt))
|
||||
return false;
|
||||
|
||||
m_stringPoolList.push_back(dbc.AutoProduceStrings(fmt,(char*)m_dataTable));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void Clear()
|
||||
{
|
||||
if (!indexTable)
|
||||
return;
|
||||
|
||||
delete[] ((char*)indexTable);
|
||||
indexTable = NULL;
|
||||
delete[] ((char*)m_dataTable);
|
||||
m_dataTable = NULL;
|
||||
|
||||
while(!m_stringPoolList.empty())
|
||||
{
|
||||
delete[] m_stringPoolList.front();
|
||||
m_stringPoolList.pop_front();
|
||||
}
|
||||
nCount = 0;
|
||||
}
|
||||
|
||||
private:
|
||||
char const* fmt;
|
||||
uint32 nCount;
|
||||
uint32 fieldCount;
|
||||
T** indexTable;
|
||||
T* m_dataTable;
|
||||
StringPoolList m_stringPoolList;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,657 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
|
||||
*
|
||||
* Copyright (C) 2008-2010 Trinity <http://www.trinitycore.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; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public 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 "DatabaseEnv.h"
|
||||
#include "Config/ConfigEnv.h"
|
||||
|
||||
#include "Common.h"
|
||||
#include "../../game/UpdateFields.h"
|
||||
|
||||
#include "Util.h"
|
||||
#include "Policies/SingletonImp.h"
|
||||
#include "Platform/Define.h"
|
||||
#include "Threading.h"
|
||||
#include "Database/SqlDelayThread.h"
|
||||
#include "Database/SqlOperations.h"
|
||||
#include "Timer.h"
|
||||
|
||||
|
||||
#include <ctime>
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
|
||||
size_t Database::db_count = 0;
|
||||
|
||||
Database::Database() : mMysql(NULL)
|
||||
{
|
||||
// before first connection
|
||||
if (db_count++ == 0)
|
||||
{
|
||||
// Mysql Library Init
|
||||
mysql_library_init(-1, NULL, NULL);
|
||||
|
||||
if (!mysql_thread_safe())
|
||||
{
|
||||
sLog.outError("FATAL ERROR: Used MySQL library isn't thread-safe.");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Database::~Database()
|
||||
{
|
||||
if (m_delayThread)
|
||||
HaltDelayThread();
|
||||
|
||||
if (mMysql)
|
||||
mysql_close(mMysql);
|
||||
|
||||
// Free Mysql library pointers for last ~DB
|
||||
if (--db_count == 0)
|
||||
mysql_library_end();
|
||||
}
|
||||
|
||||
bool Database::Initialize(const char *infoString)
|
||||
{
|
||||
// Enable logging of SQL commands (usally only GM commands)
|
||||
// (See method: PExecuteLog)
|
||||
m_logSQL = sConfig.GetBoolDefault("LogSQL", false);
|
||||
m_logsDir = sConfig.GetStringDefault("LogsDir","");
|
||||
if (!m_logsDir.empty())
|
||||
{
|
||||
if ((m_logsDir.at(m_logsDir.length()-1)!='/') && (m_logsDir.at(m_logsDir.length()-1)!='\\'))
|
||||
m_logsDir.append("/");
|
||||
}
|
||||
|
||||
tranThread = NULL;
|
||||
MYSQL *mysqlInit;
|
||||
mysqlInit = mysql_init(NULL);
|
||||
if (!mysqlInit)
|
||||
{
|
||||
sLog.outError("Could not initialize Mysql connection");
|
||||
return false;
|
||||
}
|
||||
|
||||
InitDelayThread();
|
||||
|
||||
Tokens tokens = StrSplit(infoString, ";");
|
||||
|
||||
Tokens::iterator iter;
|
||||
|
||||
std::string host, port_or_socket, user, password, database;
|
||||
int port;
|
||||
char const* unix_socket;
|
||||
|
||||
iter = tokens.begin();
|
||||
|
||||
if (iter != tokens.end())
|
||||
host = *iter++;
|
||||
if (iter != tokens.end())
|
||||
port_or_socket = *iter++;
|
||||
if (iter != tokens.end())
|
||||
user = *iter++;
|
||||
if (iter != tokens.end())
|
||||
password = *iter++;
|
||||
if (iter != tokens.end())
|
||||
database = *iter++;
|
||||
|
||||
mysql_options(mysqlInit, MYSQL_SET_CHARSET_NAME, "utf8");
|
||||
#ifdef WIN32
|
||||
if (host==".") // named pipe use option (Windows)
|
||||
{
|
||||
unsigned int opt = MYSQL_PROTOCOL_PIPE;
|
||||
mysql_options(mysqlInit, MYSQL_OPT_PROTOCOL, (char const*)&opt);
|
||||
port = 0;
|
||||
unix_socket = 0;
|
||||
}
|
||||
else // generic case
|
||||
{
|
||||
port = atoi(port_or_socket.c_str());
|
||||
unix_socket = 0;
|
||||
}
|
||||
#else
|
||||
if (host==".") // socket use option (Unix/Linux)
|
||||
{
|
||||
unsigned int opt = MYSQL_PROTOCOL_SOCKET;
|
||||
mysql_options(mysqlInit, MYSQL_OPT_PROTOCOL, (char const*)&opt);
|
||||
host = "localhost";
|
||||
port = 0;
|
||||
unix_socket = port_or_socket.c_str();
|
||||
}
|
||||
else // generic case
|
||||
{
|
||||
port = atoi(port_or_socket.c_str());
|
||||
unix_socket = 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
mMysql = mysql_real_connect(mysqlInit, host.c_str(), user.c_str(),
|
||||
password.c_str(), database.c_str(), port, unix_socket, 0);
|
||||
|
||||
if (mMysql)
|
||||
{
|
||||
sLog.outDetail("Connected to MySQL database at %s", host.c_str());
|
||||
sLog.outString("MySQL client library: %s", mysql_get_client_info());
|
||||
sLog.outString("MySQL server ver: %s ", mysql_get_server_info( mMysql));
|
||||
|
||||
if (!mysql_autocommit(mMysql, 1))
|
||||
sLog.outDetail("AUTOCOMMIT SUCCESSFULLY SET TO 1");
|
||||
else
|
||||
sLog.outDetail("AUTOCOMMIT NOT SET TO 1");
|
||||
|
||||
// set connection properties to UTF8 to properly handle locales for different
|
||||
// server configs - core sends data in UTF8, so MySQL must expect UTF8 too
|
||||
PExecute("SET NAMES `utf8`");
|
||||
PExecute("SET CHARACTER SET `utf8`");
|
||||
|
||||
#if MYSQL_VERSION_ID >= 50003
|
||||
my_bool my_true = (my_bool)1;
|
||||
if (mysql_options(mMysql, MYSQL_OPT_RECONNECT, &my_true))
|
||||
sLog.outDetail("Failed to turn on MYSQL_OPT_RECONNECT.");
|
||||
else
|
||||
sLog.outDetail("Successfully turned on MYSQL_OPT_RECONNECT.");
|
||||
#else
|
||||
#warning "Your mySQL client lib version does not support reconnecting after a timeout.\nIf this causes you any trouble we advice you to upgrade your mySQL client libs to at least mySQL 5.0.13 to resolve this problem."
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
sLog.outError("Could not connect to MySQL database at %s: %s\n", host.c_str(),mysql_error(mysqlInit));
|
||||
mysql_close(mysqlInit);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
void Database::ThreadStart()
|
||||
{
|
||||
mysql_thread_init();
|
||||
}
|
||||
|
||||
void Database::ThreadEnd()
|
||||
{
|
||||
mysql_thread_end();
|
||||
}
|
||||
|
||||
void Database::escape_string(std::string& str)
|
||||
{
|
||||
if (str.empty())
|
||||
return;
|
||||
|
||||
char* buf = new char[str.size()*2+1];
|
||||
escape_string(buf,str.c_str(),str.size());
|
||||
str = buf;
|
||||
delete[] buf;
|
||||
}
|
||||
|
||||
unsigned long Database::escape_string(char *to, const char *from, unsigned long length)
|
||||
{
|
||||
if (!mMysql || !to || !from || !length)
|
||||
return 0;
|
||||
|
||||
return(mysql_real_escape_string(mMysql, to, from, length));
|
||||
}
|
||||
|
||||
|
||||
bool Database::PExecuteLog(const char * format,...)
|
||||
{
|
||||
if (!format)
|
||||
return false;
|
||||
|
||||
va_list ap;
|
||||
char szQuery [MAX_QUERY_LEN];
|
||||
va_start(ap, format);
|
||||
int res = vsnprintf(szQuery, MAX_QUERY_LEN, format, ap);
|
||||
va_end(ap);
|
||||
|
||||
if (res==-1)
|
||||
{
|
||||
sLog.outError("SQL Query truncated (and not execute) for format: %s",format);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (m_logSQL)
|
||||
{
|
||||
time_t curr;
|
||||
tm local;
|
||||
time(&curr); // get current time_t value
|
||||
local=*(localtime(&curr)); // dereference and assign
|
||||
char fName[128];
|
||||
sprintf(fName, "%04d-%02d-%02d_logSQL.sql", local.tm_year+1900, local.tm_mon+1, local.tm_mday);
|
||||
|
||||
FILE* log_file;
|
||||
std::string logsDir_fname = m_logsDir+fName;
|
||||
log_file = fopen(logsDir_fname.c_str(), "a");
|
||||
if (log_file)
|
||||
{
|
||||
fprintf(log_file, "%s;\n", szQuery);
|
||||
fclose(log_file);
|
||||
}
|
||||
else
|
||||
{
|
||||
// The file could not be opened
|
||||
sLog.outError("SQL-Logging is disabled - Log file for the SQL commands could not be openend: %s",fName);
|
||||
}
|
||||
}
|
||||
|
||||
return Execute(szQuery);
|
||||
}
|
||||
|
||||
void Database::SetResultQueue(SqlResultQueue * queue)
|
||||
{
|
||||
m_queryQueues[ACE_Based::Thread::current()] = queue;
|
||||
}
|
||||
|
||||
bool Database::_Query(const char *sql, MYSQL_RES **pResult, MYSQL_FIELD **pFields, uint64* pRowCount, uint32* pFieldCount)
|
||||
{
|
||||
if (!mMysql)
|
||||
return 0;
|
||||
|
||||
{
|
||||
// guarded block for thread-safe mySQL request
|
||||
ACE_Guard<ACE_Thread_Mutex> query_connection_guard(mMutex);
|
||||
#ifdef TRINITY_DEBUG
|
||||
uint32 _s = getMSTime();
|
||||
#endif
|
||||
if (mysql_query(mMysql, sql))
|
||||
{
|
||||
sLog.outErrorDb("SQL: %s", sql);
|
||||
sLog.outErrorDb("query ERROR: %s", mysql_error(mMysql));
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef TRINITY_DEBUG
|
||||
sLog.outDebug("[%u ms] SQL: %s", getMSTimeDiff(_s,getMSTime()), sql );
|
||||
#endif
|
||||
}
|
||||
|
||||
*pResult = mysql_store_result(mMysql);
|
||||
*pRowCount = mysql_affected_rows(mMysql);
|
||||
*pFieldCount = mysql_field_count(mMysql);
|
||||
}
|
||||
|
||||
if (!*pResult )
|
||||
return false;
|
||||
|
||||
if (!*pRowCount)
|
||||
{
|
||||
mysql_free_result(*pResult);
|
||||
return false;
|
||||
}
|
||||
|
||||
*pFields = mysql_fetch_fields(*pResult);
|
||||
return true;
|
||||
}
|
||||
|
||||
QueryResult_AutoPtr Database::Query(const char *sql)
|
||||
{
|
||||
MYSQL_RES *result = NULL;
|
||||
MYSQL_FIELD *fields = NULL;
|
||||
uint64 rowCount = 0;
|
||||
uint32 fieldCount = 0;
|
||||
|
||||
if (!_Query(sql, &result, &fields, &rowCount, &fieldCount))
|
||||
return QueryResult_AutoPtr(NULL);
|
||||
|
||||
QueryResult *queryResult = new QueryResult(result, fields, rowCount, fieldCount);
|
||||
|
||||
queryResult->NextRow();
|
||||
|
||||
return QueryResult_AutoPtr(queryResult);
|
||||
}
|
||||
|
||||
QueryResult_AutoPtr Database::PQuery(const char *format,...)
|
||||
{
|
||||
if (!format)
|
||||
return QueryResult_AutoPtr(NULL);
|
||||
|
||||
va_list ap;
|
||||
char szQuery [MAX_QUERY_LEN];
|
||||
va_start(ap, format);
|
||||
int res = vsnprintf(szQuery, MAX_QUERY_LEN, format, ap);
|
||||
va_end(ap);
|
||||
|
||||
if (res==-1)
|
||||
{
|
||||
sLog.outError("SQL Query truncated (and not execute) for format: %s",format);
|
||||
return QueryResult_AutoPtr(NULL);
|
||||
}
|
||||
|
||||
return Query(szQuery);
|
||||
}
|
||||
|
||||
QueryNamedResult* Database::QueryNamed(const char *sql)
|
||||
{
|
||||
MYSQL_RES *result = NULL;
|
||||
MYSQL_FIELD *fields = NULL;
|
||||
uint64 rowCount = 0;
|
||||
uint32 fieldCount = 0;
|
||||
|
||||
if (!_Query(sql, &result, &fields, &rowCount, &fieldCount))
|
||||
return NULL;
|
||||
|
||||
QueryFieldNames names(fieldCount);
|
||||
for (uint32 i = 0; i < fieldCount; i++)
|
||||
names[i] = fields[i].name;
|
||||
|
||||
QueryResult *queryResult = new QueryResult(result, fields, rowCount, fieldCount);
|
||||
|
||||
queryResult->NextRow();
|
||||
|
||||
return new QueryNamedResult(queryResult, names);
|
||||
}
|
||||
|
||||
QueryNamedResult* Database::PQueryNamed(const char *format,...)
|
||||
{
|
||||
if (!format)
|
||||
return NULL;
|
||||
|
||||
va_list ap;
|
||||
char szQuery [MAX_QUERY_LEN];
|
||||
va_start(ap, format);
|
||||
int res = vsnprintf(szQuery, MAX_QUERY_LEN, format, ap);
|
||||
va_end(ap);
|
||||
|
||||
if (res==-1)
|
||||
{
|
||||
sLog.outError("SQL Query truncated (and not execute) for format: %s",format);
|
||||
return false;
|
||||
}
|
||||
|
||||
return QueryNamed(szQuery);
|
||||
}
|
||||
|
||||
bool Database::Execute(const char *sql)
|
||||
{
|
||||
if (!mMysql)
|
||||
return false;
|
||||
|
||||
// don't use queued execution if it has not been initialized
|
||||
if (!m_threadBody)
|
||||
return DirectExecute(sql);
|
||||
|
||||
nMutex.acquire();
|
||||
tranThread = ACE_Based::Thread::current(); // owner of this transaction
|
||||
TransactionQueues::iterator i = m_tranQueues.find(tranThread);
|
||||
if (i != m_tranQueues.end() && i->second != NULL)
|
||||
i->second->DelayExecute(sql); // Statement for transaction
|
||||
else
|
||||
m_threadBody->Delay(new SqlStatement(sql)); // Simple sql statement
|
||||
|
||||
nMutex.release();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Database::PExecute(const char * format,...)
|
||||
{
|
||||
if (!format)
|
||||
return false;
|
||||
|
||||
va_list ap;
|
||||
char szQuery [MAX_QUERY_LEN];
|
||||
va_start(ap, format);
|
||||
int res = vsnprintf(szQuery, MAX_QUERY_LEN, format, ap);
|
||||
va_end(ap);
|
||||
|
||||
if (res==-1)
|
||||
{
|
||||
sLog.outError("SQL Query truncated (and not execute) for format: %s",format);
|
||||
return false;
|
||||
}
|
||||
|
||||
return Execute(szQuery);
|
||||
}
|
||||
|
||||
bool Database::_UpdateDataBlobValue(const uint32 guid, const uint32 field, const int32 value)
|
||||
{
|
||||
return PExecute(
|
||||
"UPDATE characters SET data="
|
||||
"CONCAT(SUBSTRING_INDEX(`data`,' ',%u),' ',"
|
||||
"GREATEST(SUBSTRING_INDEX(SUBSTRING_INDEX(`data`,' ',%u),' ',-1)+%i,0),"
|
||||
"' ',SUBSTRING_INDEX(`data`,' ',%i)) WHERE guid=%u",
|
||||
field, field+1, value, -int32(PLAYER_END-field), guid);
|
||||
}
|
||||
|
||||
bool Database::_SetDataBlobValue(const uint32 guid, const uint32 field, const uint32 value)
|
||||
{
|
||||
return PExecute(
|
||||
"UPDATE characters SET data="
|
||||
"CONCAT(SUBSTRING_INDEX(`data`,' ',%u),' ',"
|
||||
"%u,' ',SUBSTRING_INDEX(`data`,' ',%i)) WHERE guid=%u",
|
||||
field, value, -int32(PLAYER_END-field), guid);
|
||||
}
|
||||
|
||||
bool Database::DirectExecute(const char* sql)
|
||||
{
|
||||
if (!mMysql)
|
||||
return false;
|
||||
|
||||
{
|
||||
// guarded block for thread-safe mySQL request
|
||||
ACE_Guard<ACE_Thread_Mutex> query_connection_guard(mMutex);
|
||||
|
||||
#ifdef TRINITY_DEBUG
|
||||
uint32 _s = getMSTime();
|
||||
#endif
|
||||
if (mysql_query(mMysql, sql))
|
||||
{
|
||||
sLog.outErrorDb("SQL: %s", sql);
|
||||
sLog.outErrorDb("SQL ERROR: %s", mysql_error(mMysql));
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef TRINITY_DEBUG
|
||||
sLog.outDebug("[%u ms] SQL: %s", getMSTimeDiff(_s,getMSTime()), sql);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Database::DirectPExecute(const char * format,...)
|
||||
{
|
||||
if (!format)
|
||||
return false;
|
||||
|
||||
va_list ap;
|
||||
char szQuery [MAX_QUERY_LEN];
|
||||
va_start(ap, format);
|
||||
int res = vsnprintf(szQuery, MAX_QUERY_LEN, format, ap);
|
||||
va_end(ap);
|
||||
|
||||
if (res==-1)
|
||||
{
|
||||
sLog.outError("SQL Query truncated (and not execute) for format: %s",format);
|
||||
return false;
|
||||
}
|
||||
|
||||
return DirectExecute(szQuery);
|
||||
}
|
||||
|
||||
bool Database::CheckRequiredField(char const* table_name, char const* required_name)
|
||||
{
|
||||
// check required field
|
||||
QueryResult_AutoPtr result = PQuery("SELECT %s FROM %s LIMIT 1",required_name,table_name);
|
||||
if (result)
|
||||
return true;
|
||||
|
||||
// check fail, prepare readabale error message
|
||||
|
||||
// search current required_* field in DB
|
||||
QueryNamedResult* result2 = PQueryNamed("SELECT * FROM %s LIMIT 1",table_name);
|
||||
if (result2)
|
||||
{
|
||||
QueryFieldNames const& namesMap = result2->GetFieldNames();
|
||||
std::string reqName;
|
||||
for (QueryFieldNames::const_iterator itr = namesMap.begin(); itr != namesMap.end(); ++itr)
|
||||
{
|
||||
if (itr->substr(0,9)=="required_")
|
||||
{
|
||||
reqName = *itr;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
delete result2;
|
||||
|
||||
if (!reqName.empty())
|
||||
sLog.outErrorDb("Table `%s` have field `%s` but expected `%s`! Not all sql updates applied?",table_name,reqName.c_str(),required_name);
|
||||
else
|
||||
sLog.outErrorDb("Table `%s` not have required_* field but expected `%s`! Not all sql updates applied?",table_name,required_name);
|
||||
}
|
||||
else
|
||||
sLog.outErrorDb("Table `%s` fields list query fail but expected have `%s`! No records in `%s`?",table_name,required_name,table_name);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Database::_TransactionCmd(const char *sql)
|
||||
{
|
||||
if (mysql_query(mMysql, sql))
|
||||
{
|
||||
sLog.outError("SQL: %s", sql);
|
||||
sLog.outError("SQL ERROR: %s", mysql_error(mMysql));
|
||||
return false;
|
||||
}
|
||||
else
|
||||
DEBUG_LOG("SQL: %s", sql);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Database::BeginTransaction()
|
||||
{
|
||||
if (!mMysql)
|
||||
return false;
|
||||
|
||||
// don't use queued execution if it has not been initialized
|
||||
if (!m_threadBody)
|
||||
{
|
||||
if (tranThread == ACE_Based::Thread::current())
|
||||
return false; // huh? this thread already started transaction
|
||||
|
||||
mMutex.acquire();
|
||||
if (!_TransactionCmd("START TRANSACTION"))
|
||||
{
|
||||
mMutex.release(); // can't start transaction
|
||||
return false;
|
||||
}
|
||||
return true; // transaction started
|
||||
}
|
||||
|
||||
nMutex.acquire();
|
||||
tranThread = ACE_Based::Thread::current(); // owner of this transaction
|
||||
TransactionQueues::iterator i = m_tranQueues.find(tranThread);
|
||||
if (i != m_tranQueues.end() && i->second != NULL)
|
||||
// If for thread exists queue and also contains transaction
|
||||
// delete that transaction (not allow trans in trans)
|
||||
delete i->second;
|
||||
|
||||
m_tranQueues[tranThread] = new SqlTransaction();
|
||||
nMutex.release();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Database::CommitTransaction()
|
||||
{
|
||||
if (!mMysql)
|
||||
return false;
|
||||
|
||||
bool _res = false;
|
||||
|
||||
// don't use queued execution if it has not been initialized
|
||||
if (!m_threadBody)
|
||||
{
|
||||
if (tranThread != ACE_Based::Thread::current())
|
||||
return false;
|
||||
|
||||
_res = _TransactionCmd("COMMIT");
|
||||
tranThread = NULL;
|
||||
mMutex.release();
|
||||
return _res;
|
||||
}
|
||||
|
||||
nMutex.acquire();
|
||||
tranThread = ACE_Based::Thread::current();
|
||||
TransactionQueues::iterator i = m_tranQueues.find(tranThread);
|
||||
if (i != m_tranQueues.end() && i->second != NULL)
|
||||
{
|
||||
m_threadBody->Delay(i->second);
|
||||
m_tranQueues.erase(i);
|
||||
_res = true;
|
||||
}
|
||||
nMutex.release();
|
||||
return _res;
|
||||
}
|
||||
|
||||
bool Database::RollbackTransaction()
|
||||
{
|
||||
if (!mMysql)
|
||||
return false;
|
||||
|
||||
// don't use queued execution if it has not been initialized
|
||||
if (!m_threadBody)
|
||||
{
|
||||
if (tranThread != ACE_Based::Thread::current())
|
||||
return false;
|
||||
|
||||
bool _res = _TransactionCmd("ROLLBACK");
|
||||
tranThread = NULL;
|
||||
mMutex.release();
|
||||
return _res;
|
||||
}
|
||||
|
||||
nMutex.acquire();
|
||||
tranThread = ACE_Based::Thread::current();
|
||||
TransactionQueues::iterator i = m_tranQueues.find(tranThread);
|
||||
if (i != m_tranQueues.end() && i->second != NULL)
|
||||
{
|
||||
delete i->second;
|
||||
i->second = NULL;
|
||||
m_tranQueues.erase(i);
|
||||
}
|
||||
nMutex.release();
|
||||
return true;
|
||||
}
|
||||
|
||||
void Database::InitDelayThread()
|
||||
{
|
||||
assert(!m_delayThread);
|
||||
|
||||
//New delay thread for delay execute
|
||||
m_threadBody = new SqlDelayThread(this); // will deleted at m_delayThread delete
|
||||
m_delayThread = new ACE_Based::Thread(m_threadBody);
|
||||
}
|
||||
|
||||
void Database::HaltDelayThread()
|
||||
{
|
||||
if (!m_threadBody || !m_delayThread)
|
||||
return;
|
||||
|
||||
m_threadBody->Stop(); //Stop event
|
||||
m_delayThread->wait(); //Wait for flush to DB
|
||||
delete m_delayThread; //This also deletes m_threadBody
|
||||
m_delayThread = NULL;
|
||||
m_threadBody = NULL;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,155 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
|
||||
*
|
||||
* Copyright (C) 2008-2010 Trinity <http://www.trinitycore.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; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public 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 DATABASE_H
|
||||
#define DATABASE_H
|
||||
|
||||
#include "Threading.h"
|
||||
#include "Utilities/UnorderedMap.h"
|
||||
#include "Database/SqlDelayThread.h"
|
||||
#include "Policies/Singleton.h"
|
||||
#include "ace/Thread_Mutex.h"
|
||||
#include "ace/Guard_T.h"
|
||||
|
||||
#ifdef WIN32
|
||||
#define FD_SETSIZE 1024
|
||||
#include <winsock2.h>
|
||||
#include <mysql/mysql.h>
|
||||
#else
|
||||
#include <mysql.h>
|
||||
#endif
|
||||
|
||||
class SqlTransaction;
|
||||
class SqlResultQueue;
|
||||
class SqlQueryHolder;
|
||||
|
||||
typedef UNORDERED_MAP<ACE_Based::Thread* , SqlTransaction*> TransactionQueues;
|
||||
typedef UNORDERED_MAP<ACE_Based::Thread* , SqlResultQueue*> QueryQueues;
|
||||
|
||||
#define MAX_QUERY_LEN 32*1024
|
||||
|
||||
class Database
|
||||
{
|
||||
protected:
|
||||
TransactionQueues m_tranQueues; ///< Transaction queues from diff. threads
|
||||
QueryQueues m_queryQueues; ///< Query queues from diff threads
|
||||
SqlDelayThread* m_threadBody; ///< Pointer to delay sql executer (owned by m_delayThread)
|
||||
ACE_Based::Thread* m_delayThread; ///< Pointer to executer thread
|
||||
|
||||
public:
|
||||
|
||||
Database();
|
||||
~Database();
|
||||
|
||||
/*! infoString should be formated like hostname;username;password;database. */
|
||||
bool Initialize(const char *infoString);
|
||||
|
||||
void InitDelayThread();
|
||||
void HaltDelayThread();
|
||||
|
||||
QueryResult_AutoPtr Query(const char *sql);
|
||||
QueryResult_AutoPtr PQuery(const char *format,...) ATTR_PRINTF(2,3);
|
||||
QueryNamedResult* QueryNamed(const char *sql);
|
||||
QueryNamedResult* PQueryNamed(const char *format,...) ATTR_PRINTF(2,3);
|
||||
|
||||
/// Async queries and query holders, implemented in DatabaseImpl.h
|
||||
|
||||
// Query / member
|
||||
template<class Class>
|
||||
bool AsyncQuery(Class *object, void (Class::*method)(QueryResult_AutoPtr), const char *sql);
|
||||
template<class Class, typename ParamType1>
|
||||
bool AsyncQuery(Class *object, void (Class::*method)(QueryResult_AutoPtr, ParamType1), ParamType1 param1, const char *sql);
|
||||
template<class Class, typename ParamType1, typename ParamType2>
|
||||
bool AsyncQuery(Class *object, void (Class::*method)(QueryResult_AutoPtr, ParamType1, ParamType2), ParamType1 param1, ParamType2 param2, const char *sql);
|
||||
template<class Class, typename ParamType1, typename ParamType2, typename ParamType3>
|
||||
bool AsyncQuery(Class *object, void (Class::*method)(QueryResult_AutoPtr, ParamType1, ParamType2, ParamType3), ParamType1 param1, ParamType2 param2, ParamType3 param3, const char *sql);
|
||||
// Query / static
|
||||
template<typename ParamType1>
|
||||
bool AsyncQuery(void (*method)(QueryResult_AutoPtr, ParamType1), ParamType1 param1, const char *sql);
|
||||
template<typename ParamType1, typename ParamType2>
|
||||
bool AsyncQuery(void (*method)(QueryResult_AutoPtr, ParamType1, ParamType2), ParamType1 param1, ParamType2 param2, const char *sql);
|
||||
template<typename ParamType1, typename ParamType2, typename ParamType3>
|
||||
bool AsyncQuery(void (*method)(QueryResult_AutoPtr, ParamType1, ParamType2, ParamType3), ParamType1 param1, ParamType2 param2, ParamType3 param3, const char *sql);
|
||||
// PQuery / member
|
||||
template<class Class>
|
||||
bool AsyncPQuery(Class *object, void (Class::*method)(QueryResult_AutoPtr), const char *format,...) ATTR_PRINTF(4,5);
|
||||
template<class Class, typename ParamType1>
|
||||
bool AsyncPQuery(Class *object, void (Class::*method)(QueryResult_AutoPtr, ParamType1), ParamType1 param1, const char *format,...) ATTR_PRINTF(5,6);
|
||||
template<class Class, typename ParamType1, typename ParamType2>
|
||||
bool AsyncPQuery(Class *object, void (Class::*method)(QueryResult_AutoPtr, ParamType1, ParamType2), ParamType1 param1, ParamType2 param2, const char *format,...) ATTR_PRINTF(6,7);
|
||||
template<class Class, typename ParamType1, typename ParamType2, typename ParamType3>
|
||||
bool AsyncPQuery(Class *object, void (Class::*method)(QueryResult_AutoPtr, ParamType1, ParamType2, ParamType3), ParamType1 param1, ParamType2 param2, ParamType3 param3, const char *format,...) ATTR_PRINTF(7,8);
|
||||
// PQuery / static
|
||||
template<typename ParamType1>
|
||||
bool AsyncPQuery(void (*method)(QueryResult_AutoPtr, ParamType1), ParamType1 param1, const char *format,...) ATTR_PRINTF(4,5);
|
||||
template<typename ParamType1, typename ParamType2>
|
||||
bool AsyncPQuery(void (*method)(QueryResult_AutoPtr, ParamType1, ParamType2), ParamType1 param1, ParamType2 param2, const char *format,...) ATTR_PRINTF(5,6);
|
||||
template<typename ParamType1, typename ParamType2, typename ParamType3>
|
||||
bool AsyncPQuery(void (*method)(QueryResult_AutoPtr, ParamType1, ParamType2, ParamType3), ParamType1 param1, ParamType2 param2, ParamType3 param3, const char *format,...) ATTR_PRINTF(6,7);
|
||||
template<class Class>
|
||||
// QueryHolder
|
||||
bool DelayQueryHolder(Class *object, void (Class::*method)(QueryResult_AutoPtr, SqlQueryHolder*), SqlQueryHolder *holder);
|
||||
template<class Class, typename ParamType1>
|
||||
bool DelayQueryHolder(Class *object, void (Class::*method)(QueryResult_AutoPtr, SqlQueryHolder*, ParamType1), SqlQueryHolder *holder, ParamType1 param1);
|
||||
|
||||
bool Execute(const char *sql);
|
||||
bool PExecute(const char *format,...) ATTR_PRINTF(2,3);
|
||||
bool DirectExecute(const char* sql);
|
||||
bool DirectPExecute(const char *format,...) ATTR_PRINTF(2,3);
|
||||
|
||||
bool _UpdateDataBlobValue(const uint32 guid, const uint32 field, const int32 value);
|
||||
bool _SetDataBlobValue(const uint32 guid, const uint32 field, const uint32 value);
|
||||
|
||||
// Writes SQL commands to a LOG file (see Trinityd.conf "LogSQL")
|
||||
bool PExecuteLog(const char *format,...) ATTR_PRINTF(2,3);
|
||||
|
||||
bool BeginTransaction();
|
||||
bool CommitTransaction();
|
||||
bool RollbackTransaction();
|
||||
|
||||
operator bool () const { return mMysql != NULL; }
|
||||
unsigned long escape_string(char *to, const char *from, unsigned long length);
|
||||
void escape_string(std::string& str);
|
||||
|
||||
void ThreadStart();
|
||||
void ThreadEnd();
|
||||
|
||||
// sets the result queue of the current thread, be careful what thread you call this from
|
||||
void SetResultQueue(SqlResultQueue * queue);
|
||||
|
||||
bool CheckRequiredField(char const* table_name, char const* required_name);
|
||||
|
||||
private:
|
||||
bool m_logSQL;
|
||||
std::string m_logsDir;
|
||||
ACE_Thread_Mutex mMutex; // For thread safe operations between core and mySQL server
|
||||
ACE_Thread_Mutex nMutex; // For thread safe operations on m_transQueues
|
||||
|
||||
ACE_Based::Thread * tranThread;
|
||||
|
||||
MYSQL *mMysql;
|
||||
|
||||
static size_t db_count;
|
||||
|
||||
bool _TransactionCmd(const char *sql);
|
||||
bool _Query(const char *sql, MYSQL_RES **pResult, MYSQL_FIELD **pFields, uint64* pRowCount, uint32* pFieldCount);
|
||||
};
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
|
||||
*
|
||||
* Copyright (C) 2008-2010 Trinity <http://www.trinitycore.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; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#if !defined(DATABASEENV_H)
|
||||
#define DATABASEENV_H
|
||||
|
||||
#include "Common.h"
|
||||
#include "Log.h"
|
||||
#include "Errors.h"
|
||||
|
||||
#include "Database/Field.h"
|
||||
#include "Database/QueryResult.h"
|
||||
|
||||
#include "Database/Database.h"
|
||||
typedef Database DatabaseType;
|
||||
#define _LIKE_ "LIKE"
|
||||
#define _TABLE_SIM_ "`"
|
||||
#define _CONCAT3_(A,B,C) "CONCAT( " A " , " B " , " C " )"
|
||||
#define _OFFSET_ "LIMIT %d,1"
|
||||
|
||||
extern DatabaseType WorldDatabase;
|
||||
extern DatabaseType CharacterDatabase;
|
||||
extern DatabaseType LoginDatabase;
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,234 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
|
||||
*
|
||||
* Copyright (C) 2008-2010 Trinity <http://www.trinitycore.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; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
|
||||
#include "Database/Database.h"
|
||||
#include "Database/SqlOperations.h"
|
||||
|
||||
|
||||
/// Function body definitions for the template function members of the Database class
|
||||
|
||||
|
||||
#define ASYNC_QUERY_BODY(sql, queue_itr) \
|
||||
if (!sql) return false; \
|
||||
\
|
||||
QueryQueues::iterator queue_itr; \
|
||||
\
|
||||
{ \
|
||||
ACE_Based::Thread * queryThread = ACE_Based::Thread::current(); \
|
||||
queue_itr = m_queryQueues.find(queryThread); \
|
||||
if (queue_itr == m_queryQueues.end()) return false; \
|
||||
}
|
||||
|
||||
|
||||
#define ASYNC_PQUERY_BODY(format, szQuery) \
|
||||
if(!format) return false; \
|
||||
\
|
||||
char szQuery [MAX_QUERY_LEN]; \
|
||||
\
|
||||
{ \
|
||||
va_list ap; \
|
||||
\
|
||||
va_start(ap, format); \
|
||||
int res = vsnprintf( szQuery, MAX_QUERY_LEN, format, ap ); \
|
||||
va_end(ap); \
|
||||
\
|
||||
if(res==-1) \
|
||||
{ \
|
||||
sLog.outError("SQL Query truncated (and not execute) for format: %s",format); \
|
||||
return false; \
|
||||
} \
|
||||
}
|
||||
|
||||
|
||||
#define ASYNC_DELAYHOLDER_BODY(holder, queue_itr) \
|
||||
if (!holder) return false; \
|
||||
\
|
||||
QueryQueues::iterator queue_itr; \
|
||||
\
|
||||
{ \
|
||||
ACE_Based::Thread * queryThread = ACE_Based::Thread::current(); \
|
||||
queue_itr = m_queryQueues.find(queryThread); \
|
||||
if (queue_itr == m_queryQueues.end()) return false; \
|
||||
}
|
||||
|
||||
|
||||
// -- Query / member --
|
||||
|
||||
|
||||
template<class Class>
|
||||
bool
|
||||
Database::AsyncQuery(Class *object, void (Class::*method)(QueryResult_AutoPtr), const char *sql)
|
||||
{
|
||||
ASYNC_QUERY_BODY(sql, itr)
|
||||
return m_threadBody->Delay(new SqlQuery(sql, new Trinity::QueryCallback<Class>(object, method), itr->second));
|
||||
}
|
||||
|
||||
|
||||
template<class Class, typename ParamType1>
|
||||
bool
|
||||
Database::AsyncQuery(Class *object, void (Class::*method)(QueryResult_AutoPtr, ParamType1), ParamType1 param1, const char *sql)
|
||||
{
|
||||
ASYNC_QUERY_BODY(sql, itr)
|
||||
return m_threadBody->Delay(new SqlQuery(sql, new Trinity::QueryCallback<Class, ParamType1>(object, method, (QueryResult_AutoPtr)NULL, param1), itr->second));
|
||||
}
|
||||
|
||||
|
||||
template<class Class, typename ParamType1, typename ParamType2>
|
||||
bool
|
||||
Database::AsyncQuery(Class *object, void (Class::*method)(QueryResult_AutoPtr, ParamType1, ParamType2), ParamType1 param1, ParamType2 param2, const char *sql)
|
||||
{
|
||||
ASYNC_QUERY_BODY(sql, itr)
|
||||
return m_threadBody->Delay(new SqlQuery(sql, new Trinity::QueryCallback<Class, ParamType1, ParamType2>(object, method, (QueryResult_AutoPtr)NULL, param1, param2), itr->second));
|
||||
}
|
||||
|
||||
|
||||
template<class Class, typename ParamType1, typename ParamType2, typename ParamType3>
|
||||
bool
|
||||
Database::AsyncQuery(Class *object, void (Class::*method)(QueryResult_AutoPtr, ParamType1, ParamType2, ParamType3), ParamType1 param1, ParamType2 param2, ParamType3 param3, const char *sql)
|
||||
{
|
||||
ASYNC_QUERY_BODY(sql, itr)
|
||||
return m_threadBody->Delay(new SqlQuery(sql, new Trinity::QueryCallback<Class, ParamType1, ParamType2, ParamType3>(object, method, (QueryResult_AutoPtr)NULL, param1, param2, param3), itr->second));
|
||||
}
|
||||
|
||||
|
||||
// -- Query / static --
|
||||
|
||||
|
||||
template<typename ParamType1>
|
||||
bool
|
||||
Database::AsyncQuery(void (*method)(QueryResult_AutoPtr, ParamType1), ParamType1 param1, const char *sql)
|
||||
{
|
||||
ASYNC_QUERY_BODY(sql, itr)
|
||||
return m_threadBody->Delay(new SqlQuery(sql, new Trinity::SQueryCallback<ParamType1>(method, (QueryResult_AutoPtr)NULL, param1), itr->second));
|
||||
}
|
||||
|
||||
|
||||
template<typename ParamType1, typename ParamType2>
|
||||
bool
|
||||
Database::AsyncQuery(void (*method)(QueryResult_AutoPtr, ParamType1, ParamType2), ParamType1 param1, ParamType2 param2, const char *sql)
|
||||
{
|
||||
ASYNC_QUERY_BODY(sql, itr)
|
||||
return m_threadBody->Delay(new SqlQuery(sql, new Trinity::SQueryCallback<ParamType1, ParamType2>(method, (QueryResult_AutoPtr)NULL, param1, param2), itr->second));
|
||||
}
|
||||
|
||||
|
||||
template<typename ParamType1, typename ParamType2, typename ParamType3>
|
||||
bool
|
||||
Database::AsyncQuery(void (*method)(QueryResult_AutoPtr, ParamType1, ParamType2, ParamType3), ParamType1 param1, ParamType2 param2, ParamType3 param3, const char *sql)
|
||||
{
|
||||
ASYNC_QUERY_BODY(sql, itr)
|
||||
return m_threadBody->Delay(new SqlQuery(sql, new Trinity::SQueryCallback<ParamType1, ParamType2, ParamType3>(method, (QueryResult_AutoPtr)NULL, param1, param2, param3), itr->second));
|
||||
}
|
||||
|
||||
|
||||
// -- PQuery / member --
|
||||
|
||||
|
||||
template<class Class>
|
||||
bool
|
||||
Database::AsyncPQuery(Class *object, void (Class::*method)(QueryResult_AutoPtr), const char *format,...)
|
||||
{
|
||||
ASYNC_PQUERY_BODY(format, szQuery)
|
||||
return AsyncQuery(object, method, szQuery);
|
||||
}
|
||||
|
||||
|
||||
template<class Class, typename ParamType1>
|
||||
bool
|
||||
Database::AsyncPQuery(Class *object, void (Class::*method)(QueryResult_AutoPtr, ParamType1), ParamType1 param1, const char *format,...)
|
||||
{
|
||||
ASYNC_PQUERY_BODY(format, szQuery)
|
||||
return AsyncQuery(object, method, param1, szQuery);
|
||||
}
|
||||
|
||||
|
||||
template<class Class, typename ParamType1, typename ParamType2>
|
||||
bool
|
||||
Database::AsyncPQuery(Class *object, void (Class::*method)(QueryResult_AutoPtr, ParamType1, ParamType2), ParamType1 param1, ParamType2 param2, const char *format,...)
|
||||
{
|
||||
ASYNC_PQUERY_BODY(format, szQuery)
|
||||
return AsyncQuery(object, method, param1, param2, szQuery);
|
||||
}
|
||||
|
||||
|
||||
template<class Class, typename ParamType1, typename ParamType2, typename ParamType3>
|
||||
bool
|
||||
Database::AsyncPQuery(Class *object, void (Class::*method)(QueryResult_AutoPtr, ParamType1, ParamType2, ParamType3), ParamType1 param1, ParamType2 param2, ParamType3 param3, const char *format,...)
|
||||
{
|
||||
ASYNC_PQUERY_BODY(format, szQuery)
|
||||
return AsyncQuery(object, method, param1, param2, param3, szQuery);
|
||||
}
|
||||
|
||||
|
||||
// -- PQuery / static --
|
||||
|
||||
|
||||
template<typename ParamType1>
|
||||
bool
|
||||
Database::AsyncPQuery(void (*method)(QueryResult_AutoPtr, ParamType1), ParamType1 param1, const char *format,...)
|
||||
{
|
||||
ASYNC_PQUERY_BODY(format, szQuery)
|
||||
return AsyncQuery(method, param1, szQuery);
|
||||
}
|
||||
|
||||
|
||||
template<typename ParamType1, typename ParamType2>
|
||||
bool
|
||||
Database::AsyncPQuery(void (*method)(QueryResult_AutoPtr, ParamType1, ParamType2), ParamType1 param1, ParamType2 param2, const char *format,...)
|
||||
{
|
||||
ASYNC_PQUERY_BODY(format, szQuery)
|
||||
return AsyncQuery(method, param1, param2, szQuery);
|
||||
}
|
||||
|
||||
|
||||
template<typename ParamType1, typename ParamType2, typename ParamType3>
|
||||
bool
|
||||
Database::AsyncPQuery(void (*method)(QueryResult_AutoPtr, ParamType1, ParamType2, ParamType3), ParamType1 param1, ParamType2 param2, ParamType3 param3, const char *format,...)
|
||||
{
|
||||
ASYNC_PQUERY_BODY(format, szQuery)
|
||||
return AsyncQuery(method, param1, param2, param3, szQuery);
|
||||
}
|
||||
|
||||
|
||||
// -- QueryHolder --
|
||||
|
||||
|
||||
template<class Class>
|
||||
bool
|
||||
Database::DelayQueryHolder(Class *object, void (Class::*method)(QueryResult_AutoPtr, SqlQueryHolder*), SqlQueryHolder *holder)
|
||||
{
|
||||
ASYNC_DELAYHOLDER_BODY(holder, itr)
|
||||
return holder->Execute(new Trinity::QueryCallback<Class, SqlQueryHolder*>(object, method, (QueryResult_AutoPtr)NULL, holder), m_threadBody, itr->second);
|
||||
}
|
||||
|
||||
|
||||
template<class Class, typename ParamType1>
|
||||
bool
|
||||
Database::DelayQueryHolder(Class *object, void (Class::*method)(QueryResult_AutoPtr, SqlQueryHolder*, ParamType1), SqlQueryHolder *holder, ParamType1 param1)
|
||||
{
|
||||
ASYNC_DELAYHOLDER_BODY(holder, itr)
|
||||
return holder->Execute(new Trinity::QueryCallback<Class, SqlQueryHolder*, ParamType1>(object, method, (QueryResult_AutoPtr)NULL, holder, param1), m_threadBody, itr->second);
|
||||
}
|
||||
|
||||
|
||||
#undef ASYNC_QUERY_BODY
|
||||
#undef ASYNC_PQUERY_BODY
|
||||
#undef ASYNC_DELAYHOLDER_BODY
|
||||
@@ -0,0 +1,77 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
|
||||
*
|
||||
* Copyright (C) 2008-2010 Trinity <http://www.trinitycore.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; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public 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 "DatabaseEnv.h"
|
||||
|
||||
Field::Field() :
|
||||
mValue(NULL), mType(DB_TYPE_UNKNOWN)
|
||||
{
|
||||
}
|
||||
|
||||
Field::Field(Field &f)
|
||||
{
|
||||
const char *value;
|
||||
|
||||
value = f.GetString();
|
||||
|
||||
if (value)
|
||||
{
|
||||
mValue = new char[strlen(value) + 1];
|
||||
if (mValue)
|
||||
strcpy(mValue, value);
|
||||
}
|
||||
else
|
||||
mValue = NULL;
|
||||
|
||||
mType = f.GetType();
|
||||
}
|
||||
|
||||
Field::Field(const char *value, enum Field::DataTypes type) :
|
||||
mType(type)
|
||||
{
|
||||
if (value)
|
||||
{
|
||||
mValue = new char[strlen(value) + 1];
|
||||
if (mValue)
|
||||
strcpy(mValue, value);
|
||||
}
|
||||
else
|
||||
mValue = NULL;
|
||||
}
|
||||
|
||||
Field::~Field()
|
||||
{
|
||||
if (mValue)
|
||||
delete [] mValue;
|
||||
}
|
||||
|
||||
void Field::SetValue(const char *value)
|
||||
{
|
||||
if (mValue)
|
||||
delete [] mValue;
|
||||
|
||||
if (value)
|
||||
{
|
||||
mValue = new char[strlen(value) + 1];
|
||||
strcpy(mValue, value);
|
||||
}
|
||||
else
|
||||
mValue = NULL;
|
||||
}
|
||||
@@ -0,0 +1,89 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
|
||||
*
|
||||
* Copyright (C) 2008-2010 Trinity <http://www.trinitycore.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; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#if !defined(FIELD_H)
|
||||
#define FIELD_H
|
||||
|
||||
class Field
|
||||
{
|
||||
public:
|
||||
|
||||
enum DataTypes
|
||||
{
|
||||
DB_TYPE_UNKNOWN = 0x00,
|
||||
DB_TYPE_STRING = 0x01,
|
||||
DB_TYPE_INTEGER = 0x02,
|
||||
DB_TYPE_FLOAT = 0x03,
|
||||
DB_TYPE_BOOL = 0x04
|
||||
};
|
||||
|
||||
Field();
|
||||
Field(Field &f);
|
||||
Field(const char *value, enum DataTypes type);
|
||||
|
||||
~Field();
|
||||
|
||||
enum DataTypes GetType() const { return mType; }
|
||||
|
||||
const char *GetString() const { return mValue; }
|
||||
std::string GetCppString() const
|
||||
{
|
||||
return mValue ? mValue : ""; // std::string s = 0 have undefine result in C++
|
||||
}
|
||||
float GetFloat() const { return mValue ? static_cast<float>(atof(mValue)) : 0.0f; }
|
||||
bool GetBool() const { return mValue ? atoi(mValue) > 0 : false; }
|
||||
int32 GetInt32() const { return mValue ? static_cast<int32>(atol(mValue)) : int32(0); }
|
||||
uint8 GetUInt8() const { return mValue ? static_cast<uint8>(atol(mValue)) : uint8(0); }
|
||||
uint16 GetUInt16() const { return mValue ? static_cast<uint16>(atol(mValue)) : uint16(0); }
|
||||
int16 GetInt16() const { return mValue ? static_cast<int16>(atol(mValue)) : int16(0); }
|
||||
uint32 GetUInt32() const { return mValue ? static_cast<uint32>(atol(mValue)) : uint32(0); }
|
||||
uint64 GetUInt64() const
|
||||
{
|
||||
if(mValue)
|
||||
{
|
||||
uint64 value;
|
||||
sscanf(mValue,UI64FMTD,&value);
|
||||
return value;
|
||||
}
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
uint64 GetInt64() const
|
||||
{
|
||||
if(mValue)
|
||||
{
|
||||
int64 value;
|
||||
sscanf(mValue,SI64FMTD,&value);
|
||||
return value;
|
||||
}
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
void SetType(enum DataTypes type) { mType = type; }
|
||||
|
||||
void SetValue(const char *value);
|
||||
|
||||
private:
|
||||
char *mValue;
|
||||
enum DataTypes mType;
|
||||
};
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,105 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
|
||||
*
|
||||
* Copyright (C) 2008-2010 Trinity <http://www.trinitycore.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; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public 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 "DatabaseEnv.h"
|
||||
|
||||
QueryResult::QueryResult(MYSQL_RES *result, MYSQL_FIELD *fields, uint64 rowCount, uint32 fieldCount)
|
||||
: mResult(result)
|
||||
, mFieldCount(fieldCount)
|
||||
, mRowCount(rowCount)
|
||||
{
|
||||
mCurrentRow = new Field[mFieldCount];
|
||||
ASSERT(mCurrentRow);
|
||||
|
||||
for (uint32 i = 0; i < mFieldCount; i++)
|
||||
mCurrentRow[i].SetType(ConvertNativeType(fields[i].type));
|
||||
}
|
||||
|
||||
QueryResult::~QueryResult()
|
||||
{
|
||||
EndQuery();
|
||||
}
|
||||
|
||||
bool QueryResult::NextRow()
|
||||
{
|
||||
MYSQL_ROW row;
|
||||
|
||||
if (!mResult)
|
||||
return false;
|
||||
|
||||
row = mysql_fetch_row(mResult);
|
||||
if (!row)
|
||||
{
|
||||
EndQuery();
|
||||
return false;
|
||||
}
|
||||
|
||||
for (uint32 i = 0; i < mFieldCount; i++)
|
||||
mCurrentRow[i].SetValue(row[i]);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void QueryResult::EndQuery()
|
||||
{
|
||||
if (mCurrentRow)
|
||||
{
|
||||
delete [] mCurrentRow;
|
||||
mCurrentRow = 0;
|
||||
}
|
||||
|
||||
if (mResult)
|
||||
{
|
||||
mysql_free_result(mResult);
|
||||
mResult = 0;
|
||||
}
|
||||
}
|
||||
|
||||
enum Field::DataTypes QueryResult::ConvertNativeType(enum_field_types mysqlType) const
|
||||
{
|
||||
switch (mysqlType)
|
||||
{
|
||||
case FIELD_TYPE_TIMESTAMP:
|
||||
case FIELD_TYPE_DATE:
|
||||
case FIELD_TYPE_TIME:
|
||||
case FIELD_TYPE_DATETIME:
|
||||
case FIELD_TYPE_YEAR:
|
||||
case FIELD_TYPE_STRING:
|
||||
case FIELD_TYPE_VAR_STRING:
|
||||
case FIELD_TYPE_BLOB:
|
||||
case FIELD_TYPE_SET:
|
||||
case FIELD_TYPE_NULL:
|
||||
return Field::DB_TYPE_STRING;
|
||||
case FIELD_TYPE_TINY:
|
||||
|
||||
case FIELD_TYPE_SHORT:
|
||||
case FIELD_TYPE_LONG:
|
||||
case FIELD_TYPE_INT24:
|
||||
case FIELD_TYPE_LONGLONG:
|
||||
case FIELD_TYPE_ENUM:
|
||||
return Field::DB_TYPE_INTEGER;
|
||||
case FIELD_TYPE_DECIMAL:
|
||||
case FIELD_TYPE_FLOAT:
|
||||
case FIELD_TYPE_DOUBLE:
|
||||
return Field::DB_TYPE_FLOAT;
|
||||
default:
|
||||
return Field::DB_TYPE_UNKNOWN;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,102 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
|
||||
*
|
||||
* Copyright (C) 2008-2010 Trinity <http://www.trinitycore.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; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#if !defined(QUERYRESULT_H)
|
||||
#define QUERYRESULT_H
|
||||
|
||||
#include <ace/Refcounted_Auto_Ptr.h>
|
||||
#include <ace/Null_Mutex.h>
|
||||
|
||||
#include "Field.h"
|
||||
|
||||
#ifdef WIN32
|
||||
#define FD_SETSIZE 1024
|
||||
#include <winsock2.h>
|
||||
#include <mysql/mysql.h>
|
||||
#else
|
||||
#include <mysql.h>
|
||||
#endif
|
||||
|
||||
class QueryResult
|
||||
{
|
||||
public:
|
||||
QueryResult(MYSQL_RES *result, MYSQL_FIELD *fields, uint64 rowCount, uint32 fieldCount);
|
||||
~QueryResult();
|
||||
|
||||
bool NextRow();
|
||||
|
||||
Field *Fetch() const { return mCurrentRow; }
|
||||
|
||||
const Field & operator [] (int index) const { return mCurrentRow[index]; }
|
||||
|
||||
uint32 GetFieldCount() const { return mFieldCount; }
|
||||
uint64 GetRowCount() const { return mRowCount; }
|
||||
|
||||
protected:
|
||||
Field *mCurrentRow;
|
||||
uint32 mFieldCount;
|
||||
uint64 mRowCount;
|
||||
|
||||
private:
|
||||
enum Field::DataTypes ConvertNativeType(enum_field_types mysqlType) const;
|
||||
void EndQuery();
|
||||
MYSQL_RES *mResult;
|
||||
|
||||
};
|
||||
|
||||
typedef ACE_Refcounted_Auto_Ptr<QueryResult, ACE_Null_Mutex> QueryResult_AutoPtr;
|
||||
|
||||
typedef std::vector<std::string> QueryFieldNames;
|
||||
|
||||
class QueryNamedResult
|
||||
{
|
||||
public:
|
||||
explicit QueryNamedResult(QueryResult* query, QueryFieldNames const& names) : mQuery(query), mFieldNames(names) {}
|
||||
~QueryNamedResult() { delete mQuery; }
|
||||
|
||||
// compatible interface with QueryResult
|
||||
bool NextRow() { return mQuery->NextRow(); }
|
||||
Field *Fetch() const { return mQuery->Fetch(); }
|
||||
uint32 GetFieldCount() const { return mQuery->GetFieldCount(); }
|
||||
uint64 GetRowCount() const { return mQuery->GetRowCount(); }
|
||||
Field const& operator[] (int index) const { return (*mQuery)[index]; }
|
||||
|
||||
// named access
|
||||
Field const& operator[] (const std::string &name) const { return mQuery->Fetch()[GetField_idx(name)]; }
|
||||
QueryFieldNames const& GetFieldNames() const { return mFieldNames; }
|
||||
|
||||
uint32 GetField_idx(const std::string &name) const
|
||||
{
|
||||
for (size_t idx = 0; idx < mFieldNames.size(); ++idx)
|
||||
{
|
||||
if(mFieldNames[idx] == name)
|
||||
return idx;
|
||||
}
|
||||
ASSERT(false && "unknown field name");
|
||||
return uint32(-1);
|
||||
}
|
||||
|
||||
protected:
|
||||
QueryResult *mQuery;
|
||||
QueryFieldNames mFieldNames;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,77 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
|
||||
*
|
||||
* Copyright (C) 2008-2010 Trinity <http://www.trinitycore.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; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public 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 "SQLStorage.h"
|
||||
#include "SQLStorageImpl.h"
|
||||
|
||||
extern Database WorldDatabase;
|
||||
|
||||
const char CreatureInfosrcfmt[]="iiiiiiiiiisssiiiiiiifffiffiifiiiiiiiiiiffiiiiiiiiiiiiiiiiiiiiiiiisiifffliiiiiiiliiisi";
|
||||
const char CreatureInfodstfmt[]="iiiiiiiiiisssibbiiiifffiffiifiiiiiiiiiiffiiiiiiiiiiiiiiiiiiiiiiiisiifffliiiiiiiliiiii";
|
||||
const char CreatureDataAddonInfofmt[]="iiiiiis";
|
||||
const char CreatureModelfmt[]="iffbi";
|
||||
const char CreatureInfoAddonInfofmt[]="iiiiiis";
|
||||
const char EquipmentInfofmt[]="iiii";
|
||||
const char GameObjectInfosrcfmt[]="iiissssiifiiiiiiiiiiiiiiiiiiiiiiiiiiiiiisi";
|
||||
const char GameObjectInfodstfmt[]="iiissssiifiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii";
|
||||
const char ItemPrototypesrcfmt[]="iiiisiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiffiffiiiiiiiiiifiiifiiiiiifiiiiiifiiiiiifiiiiiifiiiisiiiiiiiiiiiiiiiiiiiiiiiiifiiisiiiii";
|
||||
const char ItemPrototypedstfmt[]="iiiisiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiffiffiiiiiiiiiifiiifiiiiiifiiiiiifiiiiiifiiiiiifiiiisiiiiiiiiiiiiiiiiiiiiiiiiifiiiiiiiii";
|
||||
const char PageTextfmt[]="isii";
|
||||
const char InstanceTemplatesrcfmt[]="iiiffffsb";
|
||||
const char InstanceTemplatedstfmt[]="iiiffffib";
|
||||
|
||||
SQLStorage sCreatureStorage(CreatureInfosrcfmt, CreatureInfodstfmt, "entry","creature_template");
|
||||
SQLStorage sCreatureDataAddonStorage(CreatureDataAddonInfofmt,"guid","creature_addon");
|
||||
SQLStorage sCreatureModelStorage(CreatureModelfmt,"modelid","creature_model_info");
|
||||
SQLStorage sCreatureInfoAddonStorage(CreatureInfoAddonInfofmt,"entry","creature_template_addon");
|
||||
SQLStorage sEquipmentStorage(EquipmentInfofmt,"entry","creature_equip_template");
|
||||
SQLStorage sGOStorage(GameObjectInfosrcfmt, GameObjectInfodstfmt, "entry","gameobject_template");
|
||||
SQLStorage sItemStorage(ItemPrototypesrcfmt, ItemPrototypedstfmt, "entry","item_template");
|
||||
SQLStorage sPageTextStore(PageTextfmt,"entry","page_text");
|
||||
SQLStorage sInstanceTemplate(InstanceTemplatesrcfmt, InstanceTemplatedstfmt, "map","instance_template");
|
||||
|
||||
void SQLStorage::Free ()
|
||||
{
|
||||
uint32 offset=0;
|
||||
for (uint32 x=0; x<iNumFields; x++)
|
||||
if (dst_format[x]==FT_STRING)
|
||||
{
|
||||
for (uint32 y=0; y<MaxEntry; y++)
|
||||
if(pIndex[y])
|
||||
delete [] *(char**)((char*)(pIndex[y])+offset);
|
||||
|
||||
offset += sizeof(char*);
|
||||
}
|
||||
else if (dst_format[x]==FT_LOGIC)
|
||||
offset += sizeof(bool);
|
||||
else if (dst_format[x]==FT_BYTE)
|
||||
offset += sizeof(char);
|
||||
else
|
||||
offset += 4;
|
||||
|
||||
delete [] pIndex;
|
||||
delete [] data;
|
||||
}
|
||||
|
||||
void SQLStorage::Load()
|
||||
{
|
||||
SQLStorageLoader loader;
|
||||
loader.Load(*this);
|
||||
}
|
||||
@@ -0,0 +1,118 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
|
||||
*
|
||||
* Copyright (C) 2008-2010 Trinity <http://www.trinitycore.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; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public 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 SQLSTORAGE_H
|
||||
#define SQLSTORAGE_H
|
||||
|
||||
#include "Common.h"
|
||||
#include "Database/DatabaseEnv.h"
|
||||
|
||||
class SQLStorage
|
||||
{
|
||||
template<class T>
|
||||
friend struct SQLStorageLoaderBase;
|
||||
|
||||
public:
|
||||
|
||||
SQLStorage(const char* fmt, const char * _entry_field, const char * sqlname)
|
||||
{
|
||||
src_format = fmt;
|
||||
dst_format = fmt;
|
||||
init(_entry_field, sqlname);
|
||||
}
|
||||
|
||||
SQLStorage(const char* src_fmt, const char* dst_fmt, const char * _entry_field, const char * sqlname)
|
||||
{
|
||||
src_format = src_fmt;
|
||||
dst_format = dst_fmt;
|
||||
init(_entry_field, sqlname);
|
||||
}
|
||||
|
||||
~SQLStorage()
|
||||
{
|
||||
Free();
|
||||
}
|
||||
|
||||
template<class T>
|
||||
T const* LookupEntry(uint32 id) const
|
||||
{
|
||||
if( id == 0 )
|
||||
return NULL;
|
||||
if(id >= MaxEntry)
|
||||
return NULL;
|
||||
return reinterpret_cast<T const*>(pIndex[id]);
|
||||
}
|
||||
|
||||
uint32 RecordCount;
|
||||
uint32 MaxEntry;
|
||||
uint32 iNumFields;
|
||||
|
||||
char const* GetTableName() const { return table; }
|
||||
|
||||
void Load();
|
||||
void Free();
|
||||
|
||||
private:
|
||||
void init(const char * _entry_field, const char * sqlname)
|
||||
{
|
||||
entry_field = _entry_field;
|
||||
table=sqlname;
|
||||
data=NULL;
|
||||
pIndex=NULL;
|
||||
iNumFields = strlen(src_format);
|
||||
MaxEntry = 0;
|
||||
}
|
||||
|
||||
char** pIndex;
|
||||
|
||||
char *data;
|
||||
const char *src_format;
|
||||
const char *dst_format;
|
||||
const char *table;
|
||||
const char *entry_field;
|
||||
//bool HasString;
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct SQLStorageLoaderBase
|
||||
{
|
||||
public:
|
||||
void Load(SQLStorage &storage);
|
||||
|
||||
template<class S, class D>
|
||||
void convert(uint32 field_pos, S src, D &dst);
|
||||
template<class S>
|
||||
void convert_to_str(uint32 field_pos, S src, char * & dst);
|
||||
template<class D>
|
||||
void convert_from_str(uint32 field_pos, char * src, D& dst);
|
||||
void convert_str_to_str(uint32 field_pos, char *src, char *&dst);
|
||||
|
||||
private:
|
||||
template<class V>
|
||||
void storeValue(V value, SQLStorage &store, char *p, int x, uint32 &offset);
|
||||
void storeValue(char * value, SQLStorage &store, char *p, int x, uint32 &offset);
|
||||
};
|
||||
|
||||
struct SQLStorageLoader : public SQLStorageLoaderBase<SQLStorageLoader>
|
||||
{
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,210 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public 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 "ProgressBar.h"
|
||||
#include "Log.h"
|
||||
#include "DBCFileLoader.h"
|
||||
|
||||
template<class T>
|
||||
template<class S, class D>
|
||||
void SQLStorageLoaderBase<T>::convert(uint32 /*field_pos*/, S src, D &dst)
|
||||
{
|
||||
dst = D(src);
|
||||
}
|
||||
|
||||
template<class T>
|
||||
void SQLStorageLoaderBase<T>::convert_str_to_str(uint32 /*field_pos*/, char *src, char *&dst)
|
||||
{
|
||||
if(!src)
|
||||
{
|
||||
dst = new char[1];
|
||||
*dst = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
uint32 l = strlen(src) + 1;
|
||||
dst = new char[l];
|
||||
memcpy(dst, src, l);
|
||||
}
|
||||
}
|
||||
|
||||
template<class T>
|
||||
template<class S>
|
||||
void SQLStorageLoaderBase<T>::convert_to_str(uint32 /*field_pos*/, S /*src*/, char * & dst)
|
||||
{
|
||||
dst = new char[1];
|
||||
*dst = 0;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
template<class D>
|
||||
void SQLStorageLoaderBase<T>::convert_from_str(uint32 /*field_pos*/, char * /*src*/, D& dst)
|
||||
{
|
||||
dst = 0;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
template<class V>
|
||||
void SQLStorageLoaderBase<T>::storeValue(V value, SQLStorage &store, char *p, int x, uint32 &offset)
|
||||
{
|
||||
T * subclass = (static_cast<T*>(this));
|
||||
switch(store.dst_format[x])
|
||||
{
|
||||
case FT_LOGIC:
|
||||
subclass->convert(x, value, *((bool*)(&p[offset])) );
|
||||
offset+=sizeof(bool);
|
||||
break;
|
||||
case FT_BYTE:
|
||||
subclass->convert(x, value, *((char*)(&p[offset])) );
|
||||
offset+=sizeof(char);
|
||||
break;
|
||||
case FT_INT:
|
||||
subclass->convert(x, value, *((uint32*)(&p[offset])) );
|
||||
offset+=sizeof(uint32);
|
||||
break;
|
||||
case FT_FLOAT:
|
||||
subclass->convert(x, value, *((float*)(&p[offset])) );
|
||||
offset+=sizeof(float);
|
||||
break;
|
||||
case FT_STRING:
|
||||
subclass->convert_to_str(x, value, *((char**)(&p[offset])) );
|
||||
offset+=sizeof(char*);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
template<class T>
|
||||
void SQLStorageLoaderBase<T>::storeValue(char * value, SQLStorage &store, char *p, int x, uint32 &offset)
|
||||
{
|
||||
T * subclass = (static_cast<T*>(this));
|
||||
switch(store.dst_format[x])
|
||||
{
|
||||
case FT_LOGIC:
|
||||
subclass->convert_from_str(x, value, *((bool*)(&p[offset])) );
|
||||
offset+=sizeof(bool);
|
||||
break;
|
||||
case FT_BYTE:
|
||||
subclass->convert_from_str(x, value, *((char*)(&p[offset])) );
|
||||
offset+=sizeof(char);
|
||||
break;
|
||||
case FT_INT:
|
||||
subclass->convert_from_str(x, value, *((uint32*)(&p[offset])) );
|
||||
offset+=sizeof(uint32);
|
||||
break;
|
||||
case FT_FLOAT:
|
||||
subclass->convert_from_str(x, value, *((float*)(&p[offset])) );
|
||||
offset+=sizeof(float);
|
||||
break;
|
||||
case FT_STRING:
|
||||
subclass->convert_str_to_str(x, value, *((char**)(&p[offset])) );
|
||||
offset+=sizeof(char*);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
template<class T>
|
||||
void SQLStorageLoaderBase<T>::Load(SQLStorage &store)
|
||||
{
|
||||
uint32 maxi;
|
||||
Field *fields;
|
||||
QueryResult_AutoPtr result = WorldDatabase.PQuery("SELECT MAX(%s) FROM %s", store.entry_field, store.table);
|
||||
if(!result)
|
||||
{
|
||||
sLog.outError("Error loading %s table (not exist?)\n", store.table);
|
||||
exit(1); // Stop server at loading non exited table or not accessable table
|
||||
}
|
||||
|
||||
maxi = (*result)[0].GetUInt32()+1;
|
||||
|
||||
result = WorldDatabase.PQuery("SELECT COUNT(*) FROM %s", store.table);
|
||||
if(result)
|
||||
{
|
||||
fields = result->Fetch();
|
||||
store.RecordCount = fields[0].GetUInt32();
|
||||
}
|
||||
else
|
||||
store.RecordCount = 0;
|
||||
|
||||
result = WorldDatabase.PQuery("SELECT * FROM %s", store.table);
|
||||
|
||||
if(!result)
|
||||
{
|
||||
sLog.outError("%s table is empty!\n", store.table);
|
||||
store.RecordCount = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
uint32 recordsize = 0;
|
||||
uint32 offset = 0;
|
||||
|
||||
if(store.iNumFields != result->GetFieldCount())
|
||||
{
|
||||
store.RecordCount = 0;
|
||||
sLog.outError("Error in %s table, probably sql file format was updated (there should be %d fields in sql).\n", store.table, store.iNumFields);
|
||||
exit(1); // Stop server at loading broken or non-compatible table.
|
||||
}
|
||||
|
||||
//get struct size
|
||||
uint32 sc=0;
|
||||
uint32 bo=0;
|
||||
uint32 bb=0;
|
||||
for (uint32 x=0; x< store.iNumFields; x++)
|
||||
if(store.dst_format[x]==FT_STRING)
|
||||
++sc;
|
||||
else if (store.dst_format[x]==FT_LOGIC)
|
||||
++bo;
|
||||
else if (store.dst_format[x]==FT_BYTE)
|
||||
++bb;
|
||||
recordsize=(store.iNumFields-sc-bo-bb)*4+sc*sizeof(char*)+bo*sizeof(bool)+bb*sizeof(char);
|
||||
|
||||
char** newIndex=new char*[maxi];
|
||||
memset(newIndex,0,maxi*sizeof(char*));
|
||||
|
||||
char * _data= new char[store.RecordCount *recordsize];
|
||||
uint32 count=0;
|
||||
barGoLink bar( store.RecordCount );
|
||||
do
|
||||
{
|
||||
fields = result->Fetch();
|
||||
bar.step();
|
||||
char *p=(char*)&_data[recordsize*count];
|
||||
newIndex[fields[0].GetUInt32()]=p;
|
||||
|
||||
offset=0;
|
||||
for (uint32 x = 0; x < store.iNumFields; x++)
|
||||
switch(store.src_format[x])
|
||||
{
|
||||
case FT_LOGIC:
|
||||
storeValue((bool)(fields[x].GetUInt32() > 0), store, p, x, offset); break;
|
||||
case FT_BYTE:
|
||||
storeValue((char)fields[x].GetUInt8(), store, p, x, offset); break;
|
||||
case FT_INT:
|
||||
storeValue((uint32)fields[x].GetUInt32(), store, p, x, offset); break;
|
||||
case FT_FLOAT:
|
||||
storeValue((float)fields[x].GetFloat(), store, p, x, offset); break;
|
||||
case FT_STRING:
|
||||
storeValue((char*)fields[x].GetString(), store, p, x, offset); break;
|
||||
}
|
||||
++count;
|
||||
}while( result->NextRow() );
|
||||
|
||||
store.pIndex = newIndex;
|
||||
store.MaxEntry = maxi;
|
||||
store.data = _data;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,61 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
|
||||
*
|
||||
* Copyright (C) 2008-2010 Trinity <http://www.trinitycore.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; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include "Database/SqlDelayThread.h"
|
||||
#include "Database/SqlOperations.h"
|
||||
#include "DatabaseEnv.h"
|
||||
|
||||
SqlDelayThread::SqlDelayThread(Database* db) : m_dbEngine(db), m_running(true)
|
||||
{
|
||||
}
|
||||
|
||||
void SqlDelayThread::run()
|
||||
{
|
||||
mysql_thread_init();
|
||||
|
||||
SqlAsyncTask * s = NULL;
|
||||
|
||||
ACE_Time_Value _time(2);
|
||||
while (m_running)
|
||||
{
|
||||
// if the running state gets turned off while sleeping
|
||||
// empty the queue before exiting
|
||||
s = dynamic_cast<SqlAsyncTask*> (m_sqlQueue.dequeue());
|
||||
if (s)
|
||||
{
|
||||
s->call();
|
||||
delete s;
|
||||
}
|
||||
}
|
||||
|
||||
mysql_thread_end();
|
||||
}
|
||||
|
||||
void SqlDelayThread::Stop()
|
||||
{
|
||||
m_running = false;
|
||||
m_sqlQueue.queue()->deactivate();
|
||||
}
|
||||
|
||||
bool SqlDelayThread::Delay(SqlOperation* sql)
|
||||
{
|
||||
int res = m_sqlQueue.enqueue(new SqlAsyncTask(m_dbEngine, sql));
|
||||
return (res != -1);
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
|
||||
*
|
||||
* Copyright (C) 2008-2010 Trinity <http://www.trinitycore.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; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public 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 __SQLDELAYTHREAD_H
|
||||
#define __SQLDELAYTHREAD_H
|
||||
|
||||
#include "ace/Thread_Mutex.h"
|
||||
#include "ace/Activation_Queue.h"
|
||||
#include "Threading.h"
|
||||
|
||||
class Database;
|
||||
class SqlOperation;
|
||||
|
||||
class SqlDelayThread : public ACE_Based::Runnable
|
||||
{
|
||||
typedef ACE_Activation_Queue SqlQueue;
|
||||
|
||||
private:
|
||||
SqlQueue m_sqlQueue; ///< Queue of SQL statements
|
||||
Database* m_dbEngine; ///< Pointer to used Database engine
|
||||
volatile bool m_running;
|
||||
|
||||
SqlDelayThread();
|
||||
public:
|
||||
SqlDelayThread(Database* db);
|
||||
|
||||
///< Put sql statement to delay queue
|
||||
bool Delay(SqlOperation* sql);
|
||||
|
||||
void Stop(); ///< Stop event
|
||||
virtual void run(); ///< Main Thread loop
|
||||
};
|
||||
#endif //__SQLDELAYTHREAD_H
|
||||
@@ -0,0 +1,209 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
|
||||
*
|
||||
* Copyright (C) 2008-2010 Trinity <http://www.trinitycore.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; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public 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 "SqlOperations.h"
|
||||
#include "SqlDelayThread.h"
|
||||
#include "DatabaseEnv.h"
|
||||
#include "DatabaseImpl.h"
|
||||
|
||||
/// ---- ASYNC STATEMENTS / TRANSACTIONS ----
|
||||
|
||||
void SqlStatement::Execute(Database *db)
|
||||
{
|
||||
/// just do it
|
||||
db->DirectExecute(m_sql);
|
||||
}
|
||||
|
||||
void SqlTransaction::Execute(Database *db)
|
||||
{
|
||||
const char* sql;
|
||||
|
||||
m_Mutex.acquire();
|
||||
if (m_queue.empty())
|
||||
{
|
||||
m_Mutex.release();
|
||||
return;
|
||||
}
|
||||
|
||||
db->DirectExecute("START TRANSACTION");
|
||||
while (!m_queue.empty())
|
||||
{
|
||||
sql = m_queue.front();
|
||||
|
||||
if (!db->DirectExecute(sql))
|
||||
{
|
||||
free((void*)const_cast<char*>(sql));
|
||||
m_queue.pop();
|
||||
db->DirectExecute("ROLLBACK");
|
||||
while (!m_queue.empty())
|
||||
{
|
||||
free((void*)const_cast<char*>(m_queue.front()));
|
||||
m_queue.pop();
|
||||
}
|
||||
m_Mutex.release();
|
||||
return;
|
||||
}
|
||||
|
||||
free((void*)const_cast<char*>(sql));
|
||||
m_queue.pop();
|
||||
}
|
||||
|
||||
db->DirectExecute("COMMIT");
|
||||
m_Mutex.release();
|
||||
}
|
||||
|
||||
/// ---- ASYNC QUERIES ----
|
||||
|
||||
void SqlQuery::Execute(Database *db)
|
||||
{
|
||||
if (!m_callback || !m_queue)
|
||||
return;
|
||||
|
||||
/// execute the query and store the result in the callback
|
||||
m_callback->SetResult(db->Query(m_sql));
|
||||
/// add the callback to the sql result queue of the thread it originated from
|
||||
m_queue->add(m_callback);
|
||||
}
|
||||
|
||||
void SqlResultQueue::Update()
|
||||
{
|
||||
/// execute the callbacks waiting in the synchronization queue
|
||||
Trinity::IQueryCallback* callback;
|
||||
while (next(callback))
|
||||
{
|
||||
callback->Execute();
|
||||
delete callback;
|
||||
}
|
||||
}
|
||||
|
||||
bool SqlQueryHolder::Execute(Trinity::IQueryCallback * callback, SqlDelayThread *thread, SqlResultQueue *queue)
|
||||
{
|
||||
if (!callback || !thread || !queue)
|
||||
return false;
|
||||
|
||||
/// delay the execution of the queries, sync them with the delay thread
|
||||
/// which will in turn resync on execution (via the queue) and call back
|
||||
SqlQueryHolderEx *holderEx = new SqlQueryHolderEx(this, callback, queue);
|
||||
thread->Delay(holderEx);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SqlQueryHolder::SetQuery(size_t index, const char *sql)
|
||||
{
|
||||
if (m_queries.size() <= index)
|
||||
{
|
||||
sLog.outError("Query index (%u) out of range (size: %u) for query: %s",index,(uint32)m_queries.size(),sql);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (m_queries[index].first != NULL)
|
||||
{
|
||||
sLog.outError("Attempt assign query to holder index (%u) where other query stored (Old: [%s] New: [%s])",
|
||||
index,m_queries[index].first,sql);
|
||||
return false;
|
||||
}
|
||||
|
||||
/// not executed yet, just stored (it's not called a holder for nothing)
|
||||
m_queries[index] = SqlResultPair(strdup(sql), QueryResult_AutoPtr(NULL));
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SqlQueryHolder::SetPQuery(size_t index, const char *format, ...)
|
||||
{
|
||||
if (!format)
|
||||
{
|
||||
sLog.outError("Query (index: %u) is empty.",index);
|
||||
return false;
|
||||
}
|
||||
|
||||
va_list ap;
|
||||
char szQuery [MAX_QUERY_LEN];
|
||||
va_start(ap, format);
|
||||
int res = vsnprintf(szQuery, MAX_QUERY_LEN, format, ap);
|
||||
va_end(ap);
|
||||
|
||||
if (res==-1)
|
||||
{
|
||||
sLog.outError("SQL Query truncated (and not execute) for format: %s",format);
|
||||
return false;
|
||||
}
|
||||
|
||||
return SetQuery(index,szQuery);
|
||||
}
|
||||
|
||||
QueryResult_AutoPtr SqlQueryHolder::GetResult(size_t index)
|
||||
{
|
||||
if (index < m_queries.size())
|
||||
{
|
||||
/// the query strings are freed on the first GetResult or in the destructor
|
||||
if (m_queries[index].first != NULL)
|
||||
{
|
||||
free((void*)(const_cast<char*>(m_queries[index].first)));
|
||||
m_queries[index].first = NULL;
|
||||
}
|
||||
/// when you get a result aways remember to delete it!
|
||||
return m_queries[index].second;
|
||||
}
|
||||
else
|
||||
return QueryResult_AutoPtr(NULL);
|
||||
}
|
||||
|
||||
void SqlQueryHolder::SetResult(size_t index, QueryResult_AutoPtr result)
|
||||
{
|
||||
/// store the result in the holder
|
||||
if (index < m_queries.size())
|
||||
m_queries[index].second = result;
|
||||
}
|
||||
|
||||
SqlQueryHolder::~SqlQueryHolder()
|
||||
{
|
||||
for (size_t i = 0; i < m_queries.size(); i++)
|
||||
{
|
||||
/// if the result was never used, free the resources
|
||||
/// results used already (getresult called) are expected to be deleted
|
||||
if (m_queries[i].first != NULL)
|
||||
free((void*)(const_cast<char*>(m_queries[i].first)));
|
||||
}
|
||||
}
|
||||
|
||||
void SqlQueryHolder::SetSize(size_t size)
|
||||
{
|
||||
/// to optimize push_back, reserve the number of queries about to be executed
|
||||
m_queries.resize(size);
|
||||
}
|
||||
|
||||
void SqlQueryHolderEx::Execute(Database *db)
|
||||
{
|
||||
if (!m_holder || !m_callback || !m_queue)
|
||||
return;
|
||||
|
||||
/// we can do this, we are friends
|
||||
std::vector<SqlQueryHolder::SqlResultPair> &queries = m_holder->m_queries;
|
||||
|
||||
for (size_t i = 0; i < queries.size(); i++)
|
||||
{
|
||||
/// execute all queries in the holder and pass the results
|
||||
char const *sql = queries[i].first;
|
||||
if(sql) m_holder->SetResult(i, db->Query(sql));
|
||||
}
|
||||
|
||||
/// sync with the caller thread
|
||||
m_queue->add(m_callback);
|
||||
}
|
||||
@@ -0,0 +1,168 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
|
||||
*
|
||||
* Copyright (C) 2008-2010 Trinity <http://www.trinitycore.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; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public 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 __SQLOPERATIONS_H
|
||||
#define __SQLOPERATIONS_H
|
||||
|
||||
#include "Common.h"
|
||||
|
||||
#include "ace/Thread_Mutex.h"
|
||||
#include "ace/Method_Request.h"
|
||||
#include "LockedQueue.h"
|
||||
#include <queue>
|
||||
#include "Utilities/Callback.h"
|
||||
#include "QueryResult.h"
|
||||
|
||||
/// ---- BASE ---
|
||||
|
||||
class Database;
|
||||
class SqlDelayThread;
|
||||
|
||||
class SqlOperation
|
||||
{
|
||||
public:
|
||||
virtual void OnRemove() { delete this; }
|
||||
virtual void Execute(Database *db) = 0;
|
||||
virtual ~SqlOperation() {}
|
||||
};
|
||||
|
||||
/// ---- ASYNC STATEMENTS / TRANSACTIONS ----
|
||||
|
||||
class SqlStatement : public SqlOperation
|
||||
{
|
||||
private:
|
||||
const char *m_sql;
|
||||
public:
|
||||
SqlStatement(const char *sql) : m_sql(strdup(sql)){}
|
||||
~SqlStatement() { void* tofree = const_cast<char*>(m_sql); free(tofree); }
|
||||
void Execute(Database *db);
|
||||
};
|
||||
|
||||
class SqlTransaction : public SqlOperation
|
||||
{
|
||||
private:
|
||||
std::queue<const char*> m_queue;
|
||||
ACE_Thread_Mutex m_Mutex;
|
||||
public:
|
||||
SqlTransaction() {}
|
||||
void DelayExecute(const char *sql)
|
||||
{
|
||||
m_Mutex.acquire();
|
||||
char* _sql = strdup(sql);
|
||||
if (_sql)
|
||||
m_queue.push(_sql);
|
||||
m_Mutex.release();
|
||||
}
|
||||
void Execute(Database *db);
|
||||
};
|
||||
|
||||
/// ---- ASYNC QUERIES ----
|
||||
|
||||
class SqlQuery; /// contains a single async query
|
||||
class QueryResult; /// the result of one
|
||||
class SqlResultQueue; /// queue for thread sync
|
||||
class SqlQueryHolder; /// groups several async quries
|
||||
class SqlQueryHolderEx; /// points to a holder, added to the delay thread
|
||||
|
||||
class SqlResultQueue : public ACE_Based::LockedQueue<Trinity::IQueryCallback* , ACE_Thread_Mutex>
|
||||
{
|
||||
public:
|
||||
SqlResultQueue() {}
|
||||
void Update();
|
||||
};
|
||||
|
||||
class SqlQuery : public SqlOperation
|
||||
{
|
||||
private:
|
||||
const char *m_sql;
|
||||
Trinity::IQueryCallback * m_callback;
|
||||
SqlResultQueue * m_queue;
|
||||
public:
|
||||
SqlQuery(const char *sql, Trinity::IQueryCallback * callback, SqlResultQueue * queue)
|
||||
: m_sql(strdup(sql)), m_callback(callback), m_queue(queue) {}
|
||||
~SqlQuery() { void* tofree = const_cast<char*>(m_sql); free(tofree); }
|
||||
void Execute(Database *db);
|
||||
};
|
||||
|
||||
class SqlQueryHolder
|
||||
{
|
||||
friend class SqlQueryHolderEx;
|
||||
private:
|
||||
typedef std::pair<const char*, QueryResult_AutoPtr> SqlResultPair;
|
||||
std::vector<SqlResultPair> m_queries;
|
||||
public:
|
||||
SqlQueryHolder() {}
|
||||
~SqlQueryHolder();
|
||||
bool SetQuery(size_t index, const char *sql);
|
||||
bool SetPQuery(size_t index, const char *format, ...) ATTR_PRINTF(3,4);
|
||||
void SetSize(size_t size);
|
||||
QueryResult_AutoPtr GetResult(size_t index);
|
||||
void SetResult(size_t index, QueryResult_AutoPtr result);
|
||||
bool Execute(Trinity::IQueryCallback * callback, SqlDelayThread *thread, SqlResultQueue *queue);
|
||||
};
|
||||
|
||||
class SqlQueryHolderEx : public SqlOperation
|
||||
{
|
||||
private:
|
||||
SqlQueryHolder * m_holder;
|
||||
Trinity::IQueryCallback * m_callback;
|
||||
SqlResultQueue * m_queue;
|
||||
public:
|
||||
SqlQueryHolderEx(SqlQueryHolder *holder, Trinity::IQueryCallback * callback, SqlResultQueue * queue)
|
||||
: m_holder(holder), m_callback(callback), m_queue(queue) {}
|
||||
void Execute(Database *db);
|
||||
};
|
||||
|
||||
class SqlAsyncTask : public ACE_Method_Request
|
||||
{
|
||||
public:
|
||||
SqlAsyncTask(Database * db, SqlOperation * op) : m_db(db), m_op(op){}
|
||||
~SqlAsyncTask()
|
||||
{
|
||||
if (!m_op)
|
||||
return;
|
||||
|
||||
delete m_op;
|
||||
m_op = NULL;
|
||||
}
|
||||
|
||||
int call()
|
||||
{
|
||||
if (m_db == NULL || m_op == NULL)
|
||||
return -1;
|
||||
|
||||
try
|
||||
{
|
||||
m_op->Execute(m_db);
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
private:
|
||||
Database * m_db;
|
||||
SqlOperation * m_op;
|
||||
};
|
||||
#endif //__SQLOPERATIONS_H
|
||||
|
||||
@@ -0,0 +1,111 @@
|
||||
#include <ace/Singleton.h>
|
||||
#include <ace/Thread_Mutex.h>
|
||||
#include <ace/Log_Msg.h>
|
||||
|
||||
#include "DelayExecutor.h"
|
||||
|
||||
DelayExecutor* DelayExecutor::instance()
|
||||
{
|
||||
return ACE_Singleton<DelayExecutor, ACE_Thread_Mutex>::instance();
|
||||
}
|
||||
|
||||
DelayExecutor::DelayExecutor()
|
||||
: activated_(false), pre_svc_hook_(0), post_svc_hook_(0)
|
||||
{
|
||||
}
|
||||
|
||||
DelayExecutor::~DelayExecutor()
|
||||
{
|
||||
if (pre_svc_hook_)
|
||||
delete pre_svc_hook_;
|
||||
|
||||
if (post_svc_hook_)
|
||||
delete post_svc_hook_;
|
||||
|
||||
deactivate();
|
||||
}
|
||||
|
||||
int DelayExecutor::deactivate()
|
||||
{
|
||||
if (!activated())
|
||||
return -1;
|
||||
|
||||
activated(false);
|
||||
queue_.queue()->deactivate();
|
||||
wait();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int DelayExecutor::svc()
|
||||
{
|
||||
if (pre_svc_hook_)
|
||||
pre_svc_hook_->call();
|
||||
|
||||
for (;;)
|
||||
{
|
||||
ACE_Method_Request* rq = queue_.dequeue();
|
||||
|
||||
if (!rq)
|
||||
break;
|
||||
|
||||
rq->call();
|
||||
delete rq;
|
||||
}
|
||||
|
||||
if (post_svc_hook_)
|
||||
post_svc_hook_->call();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int DelayExecutor::activate(int num_threads, ACE_Method_Request* pre_svc_hook, ACE_Method_Request* post_svc_hook)
|
||||
{
|
||||
if (activated())
|
||||
return -1;
|
||||
|
||||
if (num_threads < 1)
|
||||
return -1;
|
||||
|
||||
if (pre_svc_hook_)
|
||||
delete pre_svc_hook_;
|
||||
|
||||
if (post_svc_hook_)
|
||||
delete post_svc_hook_;
|
||||
|
||||
pre_svc_hook_ = pre_svc_hook;
|
||||
post_svc_hook_ = post_svc_hook;
|
||||
|
||||
queue_.queue()->activate();
|
||||
|
||||
if (ACE_Task_Base::activate(THR_NEW_LWP | THR_JOINABLE | THR_INHERIT_SCHED, num_threads) == -1)
|
||||
return -1;
|
||||
|
||||
activated(true);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
int DelayExecutor::execute(ACE_Method_Request* new_req)
|
||||
{
|
||||
if (new_req == NULL)
|
||||
return -1;
|
||||
|
||||
if (queue_.enqueue(new_req, (ACE_Time_Value*)&ACE_Time_Value::zero) == -1)
|
||||
{
|
||||
delete new_req;
|
||||
ACE_ERROR_RETURN((LM_ERROR, ACE_TEXT("(%t) %p\n"), ACE_TEXT("DelayExecutor::execute enqueue")), -1);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool DelayExecutor::activated()
|
||||
{
|
||||
return activated_;
|
||||
}
|
||||
|
||||
void DelayExecutor::activated(bool s)
|
||||
{
|
||||
activated_ = s;
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
#ifndef _M_DELAY_EXECUTOR_H
|
||||
#define _M_DELAY_EXECUTOR_H
|
||||
|
||||
#include <ace/Task.h>
|
||||
#include <ace/Activation_Queue.h>
|
||||
#include <ace/Method_Request.h>
|
||||
|
||||
class DelayExecutor : protected ACE_Task_Base
|
||||
{
|
||||
public:
|
||||
|
||||
DelayExecutor();
|
||||
virtual ~DelayExecutor();
|
||||
|
||||
static DelayExecutor* instance();
|
||||
|
||||
int execute(ACE_Method_Request* new_req);
|
||||
|
||||
int activate(int num_threads = 1, ACE_Method_Request* pre_svc_hook = NULL, ACE_Method_Request* post_svc_hook = NULL);
|
||||
|
||||
int deactivate();
|
||||
|
||||
bool activated();
|
||||
|
||||
virtual int svc();
|
||||
|
||||
private:
|
||||
|
||||
ACE_Activation_Queue queue_;
|
||||
ACE_Method_Request* pre_svc_hook_;
|
||||
ACE_Method_Request* post_svc_hook_;
|
||||
bool activated_;
|
||||
|
||||
void activated(bool s);
|
||||
};
|
||||
|
||||
#endif // _M_DELAY_EXECUTOR_H
|
||||
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
|
||||
*
|
||||
* Copyright (C) 2008-2010 Trinity <http://www.trinitycore.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; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public 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 TRINITYCORE_ERRORS_H
|
||||
#define TRINITYCORE_ERRORS_H
|
||||
|
||||
#include "Common.h"
|
||||
|
||||
#if PLATFORM != PLATFORM_WINDOWS
|
||||
#ifndef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_ACE_STACK_TRACE_H
|
||||
#include "ace/Stack_Trace.h"
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_ACE_STACK_TRACE_H // old versions ACE not have Stack_Trace.h but used at some oS for better compatibility
|
||||
#define WPAssert( assertion ) { if (!(assertion)) { ACE_Stack_Trace st; fprintf( stderr, "\n%s:%i in %s ASSERTION FAILED:\n %s\n%s\n", __FILE__, __LINE__,__FUNCTION__, #assertion, st.c_str()); assert( #assertion &&0 ); } }
|
||||
#else
|
||||
#define WPAssert( assertion ) { if (!(assertion)) { fprintf( stderr, "\n%s:%i in %s ASSERTION FAILED2:\n %s\n", __FILE__, __LINE__,__FUNCTION__, #assertion); assert( #assertion &&0 ); } }
|
||||
#endif
|
||||
#define WPError( assertion, errmsg ) if( ! (assertion) ) { sLog.outError( "%\n%s:%i in %s ERROR:\n %s\n", __FILE__, __LINE__, __FUNCTION__, (char *)errmsg ); assert( false ); }
|
||||
#define WPWarning( assertion, errmsg ) if( ! (assertion) ) { sLog.outError( "\n%s:%i in %s WARNING:\n %s\n", __FILE__, __LINE__, __FUNCTION__, (char *)errmsg ); }
|
||||
|
||||
#define WPFatal( assertion, errmsg ) if( ! (assertion) ) { sLog.outError( "\n%s:%i in %s FATAL ERROR:\n %s\n", __FILE__, __LINE__, __FUNCTION__, (char *)errmsg ); assert( #assertion &&0 ); abort(); }
|
||||
|
||||
#define ASSERT WPAssert
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,139 @@
|
||||
/*
|
||||
* Copyright (C) 2009 MaNGOS <http://getmangos.com/>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public 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 LOCKEDQUEUE_H
|
||||
#define LOCKEDQUEUE_H
|
||||
|
||||
#include <ace/Guard_T.h>
|
||||
#include <ace/Thread_Mutex.h>
|
||||
#include <deque>
|
||||
#include <assert.h>
|
||||
#include "Errors.h"
|
||||
|
||||
namespace ACE_Based
|
||||
{
|
||||
template <class T, class LockType, typename StorageType=std::deque<T> >
|
||||
class LockedQueue
|
||||
{
|
||||
//! Lock access to the queue.
|
||||
LockType _lock;
|
||||
|
||||
//! Storage backing the queue.
|
||||
StorageType _queue;
|
||||
|
||||
//! Cancellation flag.
|
||||
volatile bool _canceled;
|
||||
|
||||
public:
|
||||
|
||||
//! Create a LockedQueue.
|
||||
LockedQueue()
|
||||
: _canceled(false)
|
||||
{
|
||||
}
|
||||
|
||||
//! Destroy a LockedQueue.
|
||||
virtual ~LockedQueue()
|
||||
{
|
||||
}
|
||||
|
||||
//! Adds an item to the queue.
|
||||
void add(const T& item)
|
||||
{
|
||||
lock();
|
||||
|
||||
//ASSERT(!this->_canceled);
|
||||
// throw Cancellation_Exception();
|
||||
|
||||
_queue.push_back(item);
|
||||
|
||||
unlock();
|
||||
}
|
||||
|
||||
//! Gets the next result in the queue, if any.
|
||||
bool next(T& result)
|
||||
{
|
||||
// ACE_Guard<LockType> g(this->_lock);
|
||||
ACE_GUARD_RETURN (LockType, g, this->_lock, false);
|
||||
|
||||
if (_queue.empty())
|
||||
return false;
|
||||
|
||||
//ASSERT (!_queue.empty() || !this->_canceled);
|
||||
// throw Cancellation_Exception();
|
||||
result = _queue.front();
|
||||
_queue.pop_front();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//! Peeks at the top of the queue. Remember to unlock after use.
|
||||
T& peek()
|
||||
{
|
||||
lock();
|
||||
|
||||
T& result = _queue.front();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
//! Cancels the queue.
|
||||
void cancel()
|
||||
{
|
||||
lock();
|
||||
|
||||
_canceled = true;
|
||||
|
||||
unlock();
|
||||
}
|
||||
|
||||
//! Checks if the queue is cancelled.
|
||||
bool cancelled()
|
||||
{
|
||||
ACE_Guard<LockType> g(this->_lock);
|
||||
return _canceled;
|
||||
}
|
||||
|
||||
//! Locks the queue for access.
|
||||
void lock()
|
||||
{
|
||||
this->_lock.acquire();
|
||||
}
|
||||
|
||||
//! Unlocks the queue.
|
||||
void unlock()
|
||||
{
|
||||
this->_lock.release();
|
||||
}
|
||||
|
||||
///! Calls pop_front of the queue
|
||||
void pop_front()
|
||||
{
|
||||
ACE_GUARD (LockType, g, this->_lock);
|
||||
_queue.pop_front();
|
||||
}
|
||||
|
||||
///! Checks if we're empty or not with locks held
|
||||
bool empty()
|
||||
{
|
||||
ACE_GUARD_RETURN (LockType, g, this->_lock, false);
|
||||
return _queue.empty();
|
||||
}
|
||||
};
|
||||
}
|
||||
#endif
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,190 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
|
||||
*
|
||||
* Copyright (C) 2008-2010 Trinity <http://www.trinitycore.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; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public 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 TRINITYCORE_LOG_H
|
||||
#define TRINITYCORE_LOG_H
|
||||
|
||||
#include "Common.h"
|
||||
#include "Policies/Singleton.h"
|
||||
#include "Database/DatabaseEnv.h"
|
||||
|
||||
class Config;
|
||||
|
||||
enum LogFilters
|
||||
{
|
||||
LOG_FILTER_TRANSPORT_MOVES = 1,
|
||||
LOG_FILTER_CREATURE_MOVES = 2,
|
||||
LOG_FILTER_VISIBILITY_CHANGES = 4,
|
||||
LOG_FILTER_ACHIEVEMENT_UPDATES = 8
|
||||
};
|
||||
|
||||
enum LogTypes
|
||||
{
|
||||
LOG_TYPE_STRING = 0,
|
||||
LOG_TYPE_ERROR = 1,
|
||||
LOG_TYPE_BASIC = 2,
|
||||
LOG_TYPE_DETAIL = 3,
|
||||
LOG_TYPE_DEBUG = 4,
|
||||
LOG_TYPE_CHAR = 5,
|
||||
LOG_TYPE_WORLD = 6,
|
||||
LOG_TYPE_RA = 7,
|
||||
LOG_TYPE_GM = 8,
|
||||
LOG_TYPE_CRASH = 9,
|
||||
LOG_TYPE_CHAT = 10,
|
||||
MAX_LOG_TYPES
|
||||
};
|
||||
|
||||
enum LogLevel
|
||||
{
|
||||
LOGL_NORMAL = 0,
|
||||
LOGL_BASIC,
|
||||
LOGL_DETAIL,
|
||||
LOGL_DEBUG
|
||||
};
|
||||
|
||||
const int LogLevels = int(LOGL_DEBUG)+1;
|
||||
|
||||
enum ColorTypes
|
||||
{
|
||||
BLACK,
|
||||
RED,
|
||||
GREEN,
|
||||
BROWN,
|
||||
BLUE,
|
||||
MAGENTA,
|
||||
CYAN,
|
||||
GREY,
|
||||
YELLOW,
|
||||
LRED,
|
||||
LGREEN,
|
||||
LBLUE,
|
||||
LMAGENTA,
|
||||
LCYAN,
|
||||
WHITE
|
||||
};
|
||||
|
||||
const int Colors = int(WHITE)+1;
|
||||
|
||||
class Log : public Trinity::Singleton<Log, Trinity::ClassLevelLockable<Log, ACE_Thread_Mutex> >
|
||||
{
|
||||
friend class Trinity::OperatorNew<Log>;
|
||||
Log();
|
||||
~Log();
|
||||
|
||||
public:
|
||||
void Initialize();
|
||||
|
||||
void InitColors(const std::string& init_str);
|
||||
void SetColor(bool stdout_stream, ColorTypes color);
|
||||
void ResetColor(bool stdout_stream);
|
||||
|
||||
void outDB( LogTypes type, const char * str );
|
||||
void outString( const char * str, ... ) ATTR_PRINTF(2,3);
|
||||
void outString( );
|
||||
void outStringInLine( const char * str, ... ) ATTR_PRINTF(2,3);
|
||||
void outError( const char * err, ... ) ATTR_PRINTF(2,3);
|
||||
void outCrash( const char * err, ... ) ATTR_PRINTF(2,3);
|
||||
void outBasic( const char * str, ... ) ATTR_PRINTF(2,3);
|
||||
void outDetail( const char * str, ... ) ATTR_PRINTF(2,3);
|
||||
void outDebug( const char * str, ... ) ATTR_PRINTF(2,3);
|
||||
void outDebugInLine( const char * str, ... ) ATTR_PRINTF(2,3);
|
||||
void outErrorDb( const char * str, ... ) ATTR_PRINTF(2,3);
|
||||
void outChar( const char * str, ... ) ATTR_PRINTF(2,3);
|
||||
void outCommand( uint32 account, const char * str, ...) ATTR_PRINTF(3,4);
|
||||
void outRemote( const char * str, ... ) ATTR_PRINTF(2,3);
|
||||
void outChat( const char * str, ... ) ATTR_PRINTF(2,3);
|
||||
void outArena( const char * str, ... ) ATTR_PRINTF(2,3);
|
||||
void outCharDump( const char * str, uint32 account_id, uint32 guid, const char * name );
|
||||
|
||||
static void outTimestamp(FILE* file);
|
||||
static std::string GetTimestampStr();
|
||||
|
||||
void SetLogLevel(char * Level);
|
||||
void SetLogFileLevel(char * Level);
|
||||
void SetDBLogLevel(char * Level);
|
||||
void SetRealmID(uint32 id) { realm = id; }
|
||||
|
||||
uint32 getLogFilter() const { return m_logFilter; }
|
||||
bool IsOutDebug() const { return m_logLevel > 2 || (m_logFileLevel > 2 && logfile); }
|
||||
bool IsOutCharDump() const { return m_charLog_Dump; }
|
||||
|
||||
bool GetLogDB() { return m_enableLogDB; }
|
||||
bool GetLogDBLater() { return m_enableLogDBLater; }
|
||||
void SetLogDB(bool enable) { m_enableLogDB = enable; }
|
||||
void SetLogDBLater(bool value) { m_enableLogDBLater = value; }
|
||||
private:
|
||||
FILE* openLogFile(char const* configFileName,char const* configTimeStampFlag, char const* mode);
|
||||
FILE* openGmlogPerAccount(uint32 account);
|
||||
|
||||
FILE* raLogfile;
|
||||
FILE* logfile;
|
||||
FILE* gmLogfile;
|
||||
FILE* charLogfile;
|
||||
FILE* dberLogfile;
|
||||
FILE* chatLogfile;
|
||||
FILE* arenaLogFile;
|
||||
|
||||
// cache values for after initilization use (like gm log per account case)
|
||||
std::string m_logsDir;
|
||||
std::string m_logsTimestamp;
|
||||
|
||||
// gm log control
|
||||
bool m_gmlog_per_account;
|
||||
std::string m_gmlog_filename_format;
|
||||
|
||||
bool m_enableLogDBLater;
|
||||
bool m_enableLogDB;
|
||||
uint32 realm;
|
||||
|
||||
// log coloring
|
||||
bool m_colored;
|
||||
ColorTypes m_colors[4];
|
||||
|
||||
// log levels:
|
||||
// 0 minimum/string, 1 basic/error, 2 detail, 3 full/debug
|
||||
uint8 m_dbLogLevel;
|
||||
uint8 m_logLevel;
|
||||
uint8 m_logFileLevel;
|
||||
uint8 m_logFilter;
|
||||
bool m_dbChar;
|
||||
bool m_dbRA;
|
||||
bool m_dbGM;
|
||||
bool m_dbChat;
|
||||
bool m_charLog_Dump;
|
||||
bool m_charLog_Dump_Separate;
|
||||
std::string m_dumpsDir;
|
||||
};
|
||||
|
||||
#define sLog Trinity::Singleton<Log>::Instance()
|
||||
|
||||
#ifdef TRINITY_DEBUG
|
||||
#define DEBUG_LOG Trinity::Singleton<Log>::Instance().outDebug
|
||||
#else
|
||||
#define DEBUG_LOG
|
||||
#endif
|
||||
|
||||
// primary for script library
|
||||
void outstring_log(const char * str, ...) ATTR_PRINTF(1,2);
|
||||
void detail_log(const char * str, ...) ATTR_PRINTF(1,2);
|
||||
void debug_log(const char * str, ...) ATTR_PRINTF(1,2);
|
||||
void error_log(const char * str, ...) ATTR_PRINTF(1,2);
|
||||
void error_db_log(const char * str, ...) ATTR_PRINTF(1,2);
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public 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 "MemoryLeaks.h"
|
||||
#include "Policies/SingletonImp.h"
|
||||
|
||||
INSTANTIATE_SINGLETON_1( MemoryManager ) ;
|
||||
|
||||
MemoryManager::MemoryManager( )
|
||||
{
|
||||
#if COMPILER == MICROSOFT
|
||||
// standard leak check initialization
|
||||
//_CrtSetDbgFlag( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
|
||||
// uncomment to disable Visual Leak Detector from code
|
||||
//VLDDisable();
|
||||
#endif
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public 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 TRINITYSERVER_MEMORY_H
|
||||
#define TRINITYSERVER_MEMORY_H
|
||||
|
||||
#include "Platform/CompilerDefs.h"
|
||||
|
||||
#if COMPILER == COMPILER_MICROSOFT
|
||||
|
||||
#ifndef _WIN64
|
||||
// Visual Leak Detector support enabled
|
||||
//#include <vld/vld.h>
|
||||
// standard Visual Studio leak check disabled,
|
||||
//# define _CRTDBG_MAP_ALLOC
|
||||
//# include <stdlib.h>
|
||||
//# include <crtdbg.h>
|
||||
#else
|
||||
//# define _CRTDBG_MAP_ALLOC
|
||||
//# include <stdlib.h>
|
||||
//# include <crtdbg.h>
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#include "Policies/Singleton.h"
|
||||
|
||||
struct MemoryManager : public Trinity::Singleton < MemoryManager >
|
||||
{
|
||||
MemoryManager();
|
||||
};
|
||||
#endif
|
||||
@@ -0,0 +1,160 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
|
||||
*
|
||||
* Copyright (C) 2008-2010 Trinity <http://www.trinitycore.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; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include "Common.h"
|
||||
#include "PacketLog.h"
|
||||
#include "Config/ConfigEnv.h"
|
||||
#include "Policies/SingletonImpl.h"
|
||||
|
||||
#include <ctype.h>
|
||||
|
||||
INSTANTIATE_SINGLETON_1( PacketLog );
|
||||
|
||||
PacketLog::PacketLog()
|
||||
{
|
||||
|
||||
if (sConfig.GetBoolDefault("LogRealm", false))
|
||||
{
|
||||
FILE *pFile = fopen("realm.log", "w+");
|
||||
fclose(pFile);
|
||||
}
|
||||
|
||||
if (sConfig.GetBoolDefault("LogWorld", false))
|
||||
{
|
||||
FILE *pFile = fopen("world.log", "w+");
|
||||
fclose(pFile);
|
||||
}
|
||||
}
|
||||
|
||||
PacketLog::~PacketLog()
|
||||
{
|
||||
}
|
||||
|
||||
char PacketLog::makehexchar(int i)
|
||||
{
|
||||
return (i<=9) ? '0'+i : 'A'+(i-10);
|
||||
}
|
||||
|
||||
int PacketLog::hextoint(char c)
|
||||
{
|
||||
c = toupper(c);
|
||||
return (c > '9' ? c - 'A' + 10 : c - '0');
|
||||
}
|
||||
|
||||
void PacketLog::HexDump(const unsigned char* data, size_t length, const char* file)
|
||||
{
|
||||
FILE *pFile;
|
||||
pFile = fopen(file, "a");
|
||||
|
||||
const int char_offset = 16*3 + 2;
|
||||
const int line_size = 16*3 + 16 + 3;
|
||||
char line[line_size+1];
|
||||
|
||||
fprintf(pFile,"OFFSET 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F | 0123456789ABCDEF\n");
|
||||
fprintf(pFile,"--------------------------------------------------------------------------\n");
|
||||
|
||||
line[char_offset - 1] = ' ';
|
||||
line[char_offset - 2] = ' ';
|
||||
|
||||
for (size_t i=0; i<length; )
|
||||
{
|
||||
int bi=0;
|
||||
int ci=0;
|
||||
|
||||
int start_i = i;
|
||||
|
||||
for (int line_i=0; i < length && line_i < 16; i++, line_i++)
|
||||
{
|
||||
line[bi++] = makehexchar(*data>>4);
|
||||
line[bi++] = makehexchar(*data & 0x0f);
|
||||
line[bi++] = ' ';
|
||||
line[char_offset+(ci++)]=(isprint(*data) ? *data : '.');
|
||||
++data;
|
||||
}
|
||||
|
||||
while (bi<16*3)
|
||||
{
|
||||
line[bi++]=' ';
|
||||
}
|
||||
|
||||
line[char_offset+(ci++)]='\n';
|
||||
line[char_offset+ci]=0;
|
||||
|
||||
fprintf(pFile,"%06X %s", start_i, line);
|
||||
}
|
||||
fprintf(pFile, "\n\n");
|
||||
fclose(pFile);
|
||||
}
|
||||
|
||||
void PacketLog::HexDump(const char *data, size_t length, const char* file)
|
||||
{
|
||||
HexDump((unsigned char *)data, length, file);
|
||||
}
|
||||
|
||||
void PacketLog::HexDumpStr(const char *msg, const char *data, size_t len, const char* file)
|
||||
{
|
||||
FILE *pFile;
|
||||
pFile = fopen(file, "a");
|
||||
fprintf(pFile,"%s\n", msg);
|
||||
fclose(pFile);
|
||||
|
||||
HexDump(data, len, file);
|
||||
}
|
||||
|
||||
void PacketLog::RealmHexDump(RealmPacket* data, uint32 socket, bool direction)
|
||||
{
|
||||
if (!sConfig.GetBoolDefault("LogRealm", false))
|
||||
return;
|
||||
|
||||
FILE *pFile;
|
||||
pFile = fopen("realm.log", "a");
|
||||
|
||||
uint16 len = data->size() + 2;
|
||||
uint8 opcode = data->GetOpcode();
|
||||
if (direction)
|
||||
fprintf(pFile, "SERVER:\nSOCKET: %d\nLENGTH: %d\nOPCODE: %.2X\nDATA:\n", socket, len, opcode);
|
||||
else
|
||||
fprintf(pFile, "CLIENT:\nSOCKET: %d\nLENGTH: %d\nOPCODE: %.2X\nDATA:\n", socket, len, opcode);
|
||||
|
||||
fclose(pFile);
|
||||
HexDump((char *)data->contents(), data->size(), "realm.log");
|
||||
|
||||
}
|
||||
|
||||
void PacketLog::WorldHexDump(WorldPacket* data, uint32 socket, bool direction)
|
||||
{
|
||||
if (!sConfig.GetBoolDefault("LogWorld", false))
|
||||
return;
|
||||
|
||||
FILE *pFile;
|
||||
pFile = fopen("world.log", "a");
|
||||
|
||||
uint16 len = data->size();
|
||||
uint16 opcode = data->GetOpcode();
|
||||
if (direction)
|
||||
fprintf(pFile, "SERVER:\nSOCKET: %d\nLENGTH: %d\nOPCODE: %.4X\nDATA:\n", socket, len, opcode);
|
||||
else
|
||||
fprintf(pFile, "CLIENT:\nSOCKET: %d\nLENGTH: %d\nOPCODE: %.4X\nDATA:\n", socket, len, opcode);
|
||||
|
||||
fclose(pFile);
|
||||
HexDump((char *)data->contents(), data->size(), "world.log");
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
|
||||
*
|
||||
* Copyright (C) 2008-2010 Trinity <http://www.trinitycore.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; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public 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 TRINITYCORE_PACKETLOG_H
|
||||
#define TRINITYCORE_PACKETLOG_H
|
||||
|
||||
#include "Common.h"
|
||||
#include "Policies/Singleton.h"
|
||||
#include "RealmPacket.h"
|
||||
#include "WorldPacket.h"
|
||||
|
||||
class PacketLog
|
||||
{
|
||||
public:
|
||||
PacketLog();
|
||||
~PacketLog();
|
||||
|
||||
int hextoint(char c);
|
||||
char makehexchar(int i);
|
||||
|
||||
void HexDump(const unsigned char* data, size_t length, const char* file);
|
||||
void HexDump(const char *data, size_t length, const char* file);
|
||||
void HexDumpStr(const char *msg, const char *data, size_t len, const char* file);
|
||||
|
||||
void RealmHexDump(RealmPacket * data, uint32 socket, bool direction);
|
||||
|
||||
void WorldHexDump(WorldPacket * data, uint32 socket, bool direction);
|
||||
};
|
||||
|
||||
#define sPacketLog Trinity::Singleton<PacketLog>::Instance()
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,85 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
|
||||
*
|
||||
* Copyright (C) 2008-2010 Trinity <http://www.trinitycore.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; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public 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 <stdio.h>
|
||||
|
||||
#include "ProgressBar.h"
|
||||
|
||||
char const* const barGoLink::empty = " ";
|
||||
#ifdef _WIN32
|
||||
char const* const barGoLink::full = "\x3D";
|
||||
#else
|
||||
char const* const barGoLink::full = "*";
|
||||
#endif
|
||||
|
||||
barGoLink::~barGoLink()
|
||||
{
|
||||
printf( "\n" );
|
||||
fflush(stdout);
|
||||
}
|
||||
|
||||
barGoLink::barGoLink( int row_count )
|
||||
{
|
||||
rec_no = 0;
|
||||
rec_pos = 0;
|
||||
indic_len = 50;
|
||||
num_rec = row_count;
|
||||
#ifdef _WIN32
|
||||
printf( "\x3D" );
|
||||
#else
|
||||
printf( "[" );
|
||||
#endif
|
||||
for (int i = 0; i < indic_len; i++ ) printf( empty );
|
||||
#ifdef _WIN32
|
||||
printf( "\x3D 0%%\r\x3D" );
|
||||
#else
|
||||
printf( "] 0%%\r[" );
|
||||
#endif
|
||||
fflush(stdout);
|
||||
}
|
||||
|
||||
void barGoLink::step( void )
|
||||
{
|
||||
int i, n;
|
||||
|
||||
if ( num_rec == 0 ) return;
|
||||
++rec_no;
|
||||
n = rec_no * indic_len / num_rec;
|
||||
if ( n != rec_pos )
|
||||
{
|
||||
#ifdef _WIN32
|
||||
printf( "\r\x3D" );
|
||||
#else
|
||||
printf( "\r[" );
|
||||
#endif
|
||||
for (i = 0; i < n; i++ ) printf( full );
|
||||
for (; i < indic_len; i++ ) printf( empty );
|
||||
float percent = (((float)n/(float)indic_len)*100);
|
||||
#ifdef _WIN32
|
||||
printf( "\x3D %i%% \r\x3D", (int)percent);
|
||||
#else
|
||||
printf( "] %i%% \r[", (int)percent);
|
||||
#endif
|
||||
fflush(stdout);
|
||||
|
||||
rec_pos = n;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
|
||||
*
|
||||
* Copyright (C) 2008-2010 Trinity <http://www.trinitycore.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; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public 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 TRINITYCORE_PROGRESSBAR_H
|
||||
#define TRINITYCORE_PROGRESSBAR_H
|
||||
|
||||
#include "Platform/Define.h"
|
||||
|
||||
class barGoLink
|
||||
{
|
||||
static char const * const empty;
|
||||
static char const * const full;
|
||||
|
||||
int rec_no;
|
||||
int rec_pos;
|
||||
int num_rec;
|
||||
int indic_len;
|
||||
|
||||
public:
|
||||
|
||||
void step( void );
|
||||
barGoLink( int );
|
||||
~barGoLink();
|
||||
};
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,263 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
|
||||
*
|
||||
* Copyright (C) 2008-2010 Trinity <http://www.trinitycore.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; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifdef WIN32
|
||||
|
||||
#include "Common.h"
|
||||
#include "Log.h"
|
||||
#include <cstring>
|
||||
#include <windows.h>
|
||||
#include <winsvc.h>
|
||||
|
||||
#if !defined(WINADVAPI)
|
||||
#if !defined(_ADVAPI32_)
|
||||
#define WINADVAPI DECLSPEC_IMPORT
|
||||
#else
|
||||
#define WINADVAPI
|
||||
#endif
|
||||
#endif
|
||||
|
||||
extern int main(int argc, char ** argv);
|
||||
extern char serviceLongName[];
|
||||
extern char serviceName[];
|
||||
extern char serviceDescription[];
|
||||
|
||||
extern int m_ServiceStatus;
|
||||
|
||||
SERVICE_STATUS serviceStatus;
|
||||
|
||||
SERVICE_STATUS_HANDLE serviceStatusHandle = 0;
|
||||
|
||||
typedef WINADVAPI BOOL (WINAPI *CSD_T)(SC_HANDLE, DWORD, LPCVOID);
|
||||
|
||||
bool WinServiceInstall()
|
||||
{
|
||||
CSD_T ChangeService_Config2;
|
||||
HMODULE advapi32;
|
||||
SC_HANDLE serviceControlManager = OpenSCManager(0, 0, SC_MANAGER_CREATE_SERVICE);
|
||||
|
||||
if (serviceControlManager)
|
||||
{
|
||||
char path[_MAX_PATH + 10];
|
||||
if (GetModuleFileName( 0, path, sizeof(path)/sizeof(path[0]) ) > 0)
|
||||
{
|
||||
SC_HANDLE service;
|
||||
std::strcat(path, " --service");
|
||||
service = CreateService(serviceControlManager,
|
||||
serviceName, // name of service
|
||||
serviceLongName, // service name to display
|
||||
SERVICE_ALL_ACCESS, // desired access
|
||||
// service type
|
||||
SERVICE_WIN32_OWN_PROCESS | SERVICE_INTERACTIVE_PROCESS,
|
||||
SERVICE_AUTO_START, // start type
|
||||
SERVICE_ERROR_IGNORE, // error control type
|
||||
path, // service's binary
|
||||
0, // no load ordering group
|
||||
0, // no tag identifier
|
||||
0, // no dependencies
|
||||
0, // LocalSystem account
|
||||
0); // no password
|
||||
if (service)
|
||||
{
|
||||
advapi32 = GetModuleHandle("ADVAPI32.DLL");
|
||||
if(!advapi32)
|
||||
{
|
||||
CloseServiceHandle(service);
|
||||
CloseServiceHandle(serviceControlManager);
|
||||
return false;
|
||||
}
|
||||
|
||||
ChangeService_Config2 = (CSD_T) GetProcAddress(advapi32, "ChangeServiceConfig2A");
|
||||
if (!ChangeService_Config2)
|
||||
{
|
||||
CloseServiceHandle(service);
|
||||
CloseServiceHandle(serviceControlManager);
|
||||
return false;
|
||||
}
|
||||
|
||||
SERVICE_DESCRIPTION sdBuf;
|
||||
sdBuf.lpDescription = serviceDescription;
|
||||
ChangeService_Config2(
|
||||
service, // handle to service
|
||||
SERVICE_CONFIG_DESCRIPTION, // change: description
|
||||
&sdBuf); // new data
|
||||
|
||||
SC_ACTION _action[1];
|
||||
_action[0].Type = SC_ACTION_RESTART;
|
||||
_action[0].Delay = 10000;
|
||||
SERVICE_FAILURE_ACTIONS sfa;
|
||||
ZeroMemory(&sfa, sizeof(SERVICE_FAILURE_ACTIONS));
|
||||
sfa.lpsaActions = _action;
|
||||
sfa.cActions = 1;
|
||||
sfa.dwResetPeriod =INFINITE;
|
||||
ChangeService_Config2(
|
||||
service, // handle to service
|
||||
SERVICE_CONFIG_FAILURE_ACTIONS, // information level
|
||||
&sfa); // new data
|
||||
|
||||
CloseServiceHandle(service);
|
||||
|
||||
}
|
||||
}
|
||||
CloseServiceHandle(serviceControlManager);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool WinServiceUninstall()
|
||||
{
|
||||
SC_HANDLE serviceControlManager = OpenSCManager(0, 0, SC_MANAGER_CONNECT);
|
||||
|
||||
if (serviceControlManager)
|
||||
{
|
||||
SC_HANDLE service = OpenService(serviceControlManager,
|
||||
serviceName, SERVICE_QUERY_STATUS | DELETE);
|
||||
if (service)
|
||||
{
|
||||
SERVICE_STATUS serviceStatus2;
|
||||
if (QueryServiceStatus(service, &serviceStatus2))
|
||||
{
|
||||
if (serviceStatus2.dwCurrentState == SERVICE_STOPPED)
|
||||
DeleteService(service);
|
||||
}
|
||||
CloseServiceHandle(service);
|
||||
}
|
||||
|
||||
CloseServiceHandle(serviceControlManager);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void WINAPI ServiceControlHandler(DWORD controlCode)
|
||||
{
|
||||
switch (controlCode)
|
||||
{
|
||||
case SERVICE_CONTROL_INTERROGATE:
|
||||
break;
|
||||
|
||||
case SERVICE_CONTROL_SHUTDOWN:
|
||||
case SERVICE_CONTROL_STOP:
|
||||
serviceStatus.dwCurrentState = SERVICE_STOP_PENDING;
|
||||
SetServiceStatus(serviceStatusHandle, &serviceStatus);
|
||||
|
||||
m_ServiceStatus = 0;
|
||||
return;
|
||||
|
||||
case SERVICE_CONTROL_PAUSE:
|
||||
m_ServiceStatus = 2;
|
||||
serviceStatus.dwCurrentState = SERVICE_PAUSED;
|
||||
SetServiceStatus(serviceStatusHandle, &serviceStatus);
|
||||
break;
|
||||
|
||||
case SERVICE_CONTROL_CONTINUE:
|
||||
serviceStatus.dwCurrentState = SERVICE_RUNNING;
|
||||
SetServiceStatus(serviceStatusHandle, &serviceStatus);
|
||||
m_ServiceStatus = 1;
|
||||
break;
|
||||
|
||||
default:
|
||||
if ( controlCode >= 128 && controlCode <= 255 )
|
||||
// user defined control code
|
||||
break;
|
||||
else
|
||||
// unrecognized control code
|
||||
break;
|
||||
}
|
||||
|
||||
SetServiceStatus(serviceStatusHandle, &serviceStatus);
|
||||
}
|
||||
|
||||
void WINAPI ServiceMain(DWORD argc, char *argv[])
|
||||
{
|
||||
// initialise service status
|
||||
serviceStatus.dwServiceType = SERVICE_WIN32;
|
||||
serviceStatus.dwCurrentState = SERVICE_START_PENDING;
|
||||
serviceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_PAUSE_CONTINUE;
|
||||
serviceStatus.dwWin32ExitCode = NO_ERROR;
|
||||
serviceStatus.dwServiceSpecificExitCode = NO_ERROR;
|
||||
serviceStatus.dwCheckPoint = 0;
|
||||
serviceStatus.dwWaitHint = 0;
|
||||
|
||||
serviceStatusHandle = RegisterServiceCtrlHandler(serviceName, ServiceControlHandler);
|
||||
|
||||
if ( serviceStatusHandle )
|
||||
{
|
||||
char path[_MAX_PATH + 1];
|
||||
unsigned int i, last_slash = 0;
|
||||
|
||||
GetModuleFileName(0, path, sizeof(path)/sizeof(path[0]));
|
||||
|
||||
for (i = 0; i < std::strlen(path); i++)
|
||||
{
|
||||
if (path[i] == '\\') last_slash = i;
|
||||
}
|
||||
|
||||
path[last_slash] = 0;
|
||||
|
||||
// service is starting
|
||||
serviceStatus.dwCurrentState = SERVICE_START_PENDING;
|
||||
SetServiceStatus(serviceStatusHandle, &serviceStatus);
|
||||
|
||||
// do initialisation here
|
||||
SetCurrentDirectory(path);
|
||||
|
||||
// running
|
||||
serviceStatus.dwControlsAccepted |= (SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN);
|
||||
serviceStatus.dwCurrentState = SERVICE_RUNNING;
|
||||
SetServiceStatus( serviceStatusHandle, &serviceStatus );
|
||||
|
||||
////////////////////////
|
||||
// service main cycle //
|
||||
////////////////////////
|
||||
|
||||
m_ServiceStatus = 1;
|
||||
argc = 1;
|
||||
main(argc , argv);
|
||||
|
||||
// service was stopped
|
||||
serviceStatus.dwCurrentState = SERVICE_STOP_PENDING;
|
||||
SetServiceStatus(serviceStatusHandle, &serviceStatus);
|
||||
|
||||
// do cleanup here
|
||||
|
||||
// service is now stopped
|
||||
serviceStatus.dwControlsAccepted &= ~(SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN);
|
||||
serviceStatus.dwCurrentState = SERVICE_STOPPED;
|
||||
SetServiceStatus(serviceStatusHandle, &serviceStatus);
|
||||
}
|
||||
}
|
||||
|
||||
bool WinServiceRun()
|
||||
{
|
||||
SERVICE_TABLE_ENTRY serviceTable[] =
|
||||
{
|
||||
{ serviceName, ServiceMain },
|
||||
{ 0, 0 }
|
||||
};
|
||||
|
||||
if (!StartServiceCtrlDispatcher(serviceTable))
|
||||
{
|
||||
sLog.outError("StartService Failed. Error [%u]", ::GetLastError());
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
|
||||
*
|
||||
* Copyright (C) 2008-2010 Trinity <http://www.trinitycore.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; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifdef WIN32
|
||||
#ifndef _WIN32_SERVICE_
|
||||
#define _WIN32_SERVICE_
|
||||
|
||||
bool WinServiceInstall();
|
||||
bool WinServiceUninstall();
|
||||
bool WinServiceRun();
|
||||
|
||||
#endif // _WIN32_SERVICE_
|
||||
#endif // WIN32
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2010 MaNGOS <http://getmangos.com/>
|
||||
*
|
||||
* Copyright (C) 2008-2010 Trinity <http://www.trinitycore.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; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public 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 __SIGNAL_HANDLER_H__
|
||||
#define __SIGNAL_HANDLER_H__
|
||||
|
||||
#include <ace/Event_Handler.h>
|
||||
|
||||
namespace Trinity
|
||||
{
|
||||
|
||||
/// Handle termination signals
|
||||
class SignalHandler : public ACE_Event_Handler
|
||||
{
|
||||
public:
|
||||
int handle_signal(int SigNum, siginfo_t* = NULL, ucontext_t* = NULL)
|
||||
{
|
||||
HandleSignal(SigNum);
|
||||
return 0;
|
||||
}
|
||||
virtual void HandleSignal(int SigNum) {};
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif /* __SIGNAL_HANDLER_H__ */
|
||||
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
|
||||
*
|
||||
* Copyright (C) 2008-2010 Trinity <http://www.trinitycore.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; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
// THIS FILE IS DEPRECATED
|
||||
|
||||
#ifndef TRINITY_SYSTEMCONFIG_H
|
||||
#define TRINITY_SYSTEMCONFIG_H
|
||||
|
||||
#include "Platform/Define.h"
|
||||
#include "revision.h"
|
||||
|
||||
#define _PACKAGENAME "TrinityCore "
|
||||
#define _CODENAME "LONG_COLD_WINTER"
|
||||
|
||||
#if TRINITY_ENDIAN == TRINITY_BIGENDIAN
|
||||
# define _ENDIAN_STRING "big-endian"
|
||||
#else
|
||||
# define _ENDIAN_STRING "little-endian"
|
||||
#endif
|
||||
|
||||
#if PLATFORM == PLATFORM_WINDOWS
|
||||
# ifdef _WIN64
|
||||
# define _FULLVERSION _PACKAGENAME "Rev: " _REVISION " " _BUILD_DIRECTIVE " Hash: " _HASH " (Win64," _ENDIAN_STRING ")"
|
||||
# else
|
||||
# define _FULLVERSION _PACKAGENAME "Rev: " _REVISION " " _BUILD_DIRECTIVE " Hash: " _HASH " (Win32," _ENDIAN_STRING ")"
|
||||
# endif
|
||||
#else
|
||||
# define _FULLVERSION _PACKAGENAME "Rev: " _REVISION " " _BUILD_DIRECTIVE " Hash: " _HASH " (Unix," _ENDIAN_STRING ")"
|
||||
#endif
|
||||
|
||||
#define DEFAULT_PLAYER_LIMIT 100
|
||||
#define DEFAULT_WORLDSERVER_PORT 8085 //8129
|
||||
#define DEFAULT_REALMSERVER_PORT 3724
|
||||
#define DEFAULT_SOCKET_SELECT_TIME 10000
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,232 @@
|
||||
/*
|
||||
* Copyright (C) 2009 MaNGOS <http://getmangos.com/>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public 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 "Threading.h"
|
||||
#include "Errors.h"
|
||||
#include <ace/OS_NS_unistd.h>
|
||||
#include <ace/Sched_Params.h>
|
||||
#include <vector>
|
||||
|
||||
using namespace ACE_Based;
|
||||
|
||||
ThreadPriority::ThreadPriority()
|
||||
{
|
||||
for (int i = Idle; i < MAXPRIORITYNUM; ++i)
|
||||
m_priority[i] = ACE_THR_PRI_OTHER_DEF;
|
||||
|
||||
m_priority[Idle] = ACE_Sched_Params::priority_min(ACE_SCHED_OTHER);
|
||||
m_priority[Realtime] = ACE_Sched_Params::priority_max(ACE_SCHED_OTHER);
|
||||
|
||||
std::vector<int> _tmp;
|
||||
|
||||
ACE_Sched_Params::Policy _policy = ACE_SCHED_OTHER;
|
||||
ACE_Sched_Priority_Iterator pr_iter(_policy);
|
||||
|
||||
while (pr_iter.more())
|
||||
{
|
||||
_tmp.push_back(pr_iter.priority());
|
||||
pr_iter.next();
|
||||
}
|
||||
|
||||
ASSERT (!_tmp.empty());
|
||||
|
||||
if(_tmp.size() >= MAXPRIORITYNUM)
|
||||
{
|
||||
const size_t max_pos = _tmp.size();
|
||||
size_t min_pos = 1;
|
||||
size_t norm_pos = 0;
|
||||
for (size_t i = 0; i < max_pos; ++i)
|
||||
{
|
||||
if(_tmp[i] == ACE_THR_PRI_OTHER_DEF)
|
||||
{
|
||||
norm_pos = i + 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//since we have only 7(seven) values in enum Priority
|
||||
//and 3 we know already (Idle, Normal, Realtime) so
|
||||
//we need to split each list [Idle...Normal] and [Normal...Realtime]
|
||||
//into ¹ piesces
|
||||
const size_t _divider = 4;
|
||||
size_t _div = (norm_pos - min_pos) / _divider;
|
||||
if(_div == 0)
|
||||
_div = 1;
|
||||
|
||||
min_pos = (norm_pos - 1);
|
||||
|
||||
m_priority[Low] = _tmp[min_pos -= _div];
|
||||
m_priority[Lowest] = _tmp[min_pos -= _div ];
|
||||
|
||||
_div = (max_pos - norm_pos) / _divider;
|
||||
if(_div == 0)
|
||||
_div = 1;
|
||||
|
||||
min_pos = norm_pos - 1;
|
||||
|
||||
m_priority[High] = _tmp[min_pos += _div];
|
||||
m_priority[Highest] = _tmp[min_pos += _div];
|
||||
}
|
||||
}
|
||||
|
||||
int ThreadPriority::getPriority(Priority p) const
|
||||
{
|
||||
if(p < Idle)
|
||||
p = Idle;
|
||||
|
||||
if(p > Realtime)
|
||||
p = Realtime;
|
||||
|
||||
return m_priority[p];
|
||||
}
|
||||
|
||||
#define THREADFLAG (THR_NEW_LWP | THR_SCHED_DEFAULT| THR_JOINABLE)
|
||||
|
||||
Thread::Thread() : m_task(0), m_iThreadId(0), m_hThreadHandle(0)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
Thread::Thread(Runnable* instance) : m_task(instance), m_iThreadId(0), m_hThreadHandle(0)
|
||||
{
|
||||
// register reference to m_task to prevent it deeltion until destructor
|
||||
if (m_task)
|
||||
m_task->incReference();
|
||||
|
||||
bool _start = start();
|
||||
ASSERT (_start);
|
||||
}
|
||||
|
||||
Thread::~Thread()
|
||||
{
|
||||
//Wait();
|
||||
|
||||
// deleted runnable object (if no other references)
|
||||
if (m_task)
|
||||
m_task->decReference();
|
||||
}
|
||||
|
||||
//initialize Thread's class static member
|
||||
Thread::ThreadStorage Thread::m_ThreadStorage;
|
||||
ThreadPriority Thread::m_TpEnum;
|
||||
|
||||
bool Thread::start()
|
||||
{
|
||||
if (m_task == 0 || m_iThreadId != 0)
|
||||
return false;
|
||||
|
||||
bool res = (ACE_Thread::spawn(&Thread::ThreadTask, (void*)m_task, THREADFLAG, &m_iThreadId, &m_hThreadHandle) == 0);
|
||||
|
||||
if (res)
|
||||
m_task->incReference();
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
bool Thread::wait()
|
||||
{
|
||||
if (!m_hThreadHandle || !m_task)
|
||||
return false;
|
||||
|
||||
ACE_THR_FUNC_RETURN _value = ACE_THR_FUNC_RETURN(-1);
|
||||
int _res = ACE_Thread::join(m_hThreadHandle, &_value);
|
||||
|
||||
m_iThreadId = 0;
|
||||
m_hThreadHandle = 0;
|
||||
|
||||
return (_res == 0);
|
||||
}
|
||||
|
||||
void Thread::destroy()
|
||||
{
|
||||
if (!m_iThreadId || !m_task)
|
||||
return;
|
||||
|
||||
if (ACE_Thread::kill(m_iThreadId, -1) != 0)
|
||||
return;
|
||||
|
||||
m_iThreadId = 0;
|
||||
m_hThreadHandle = 0;
|
||||
|
||||
// reference set at ACE_Thread::spawn
|
||||
m_task->decReference();
|
||||
}
|
||||
|
||||
void Thread::suspend()
|
||||
{
|
||||
ACE_Thread::suspend(m_hThreadHandle);
|
||||
}
|
||||
|
||||
void Thread::resume()
|
||||
{
|
||||
ACE_Thread::resume(m_hThreadHandle);
|
||||
}
|
||||
|
||||
ACE_THR_FUNC_RETURN Thread::ThreadTask(void * param)
|
||||
{
|
||||
Runnable * _task = (Runnable*)param;
|
||||
_task->run();
|
||||
|
||||
// task execution complete, free referecne added at
|
||||
_task->decReference();
|
||||
|
||||
return (ACE_THR_FUNC_RETURN)0;
|
||||
}
|
||||
|
||||
ACE_thread_t Thread::currentId()
|
||||
{
|
||||
return ACE_Thread::self();
|
||||
}
|
||||
|
||||
ACE_hthread_t Thread::currentHandle()
|
||||
{
|
||||
ACE_hthread_t _handle;
|
||||
ACE_Thread::self(_handle);
|
||||
|
||||
return _handle;
|
||||
}
|
||||
|
||||
Thread * Thread::current()
|
||||
{
|
||||
Thread * _thread = m_ThreadStorage.ts_object();
|
||||
if(!_thread)
|
||||
{
|
||||
_thread = new Thread();
|
||||
_thread->m_iThreadId = Thread::currentId();
|
||||
_thread->m_hThreadHandle = Thread::currentHandle();
|
||||
|
||||
Thread * _oldValue = m_ThreadStorage.ts_object(_thread);
|
||||
if(_oldValue)
|
||||
delete _oldValue;
|
||||
}
|
||||
|
||||
return _thread;
|
||||
}
|
||||
|
||||
void Thread::setPriority(Priority type)
|
||||
{
|
||||
int _priority = m_TpEnum.getPriority(type);
|
||||
int _ok = ACE_Thread::setprio(m_hThreadHandle, _priority);
|
||||
//remove this ASSERT in case you don't want to know is thread priority change was successful or not
|
||||
ASSERT (_ok == 0);
|
||||
}
|
||||
|
||||
void Thread::Sleep(unsigned long msecs)
|
||||
{
|
||||
ACE_OS::sleep(ACE_Time_Value(0, 1000 * msecs));
|
||||
}
|
||||
@@ -0,0 +1,108 @@
|
||||
/*
|
||||
* Copyright (C) 2009 MaNGOS <http://getmangos.com/>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public 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 THREADING_H
|
||||
#define THREADING_H
|
||||
|
||||
#include <ace/Thread.h>
|
||||
#include <ace/TSS_T.h>
|
||||
#include "ace/Atomic_Op.h"
|
||||
#include <assert.h>
|
||||
|
||||
namespace ACE_Based
|
||||
{
|
||||
|
||||
class Runnable
|
||||
{
|
||||
public:
|
||||
virtual ~Runnable() {}
|
||||
virtual void run() = 0;
|
||||
|
||||
void incReference() { ++m_refs; }
|
||||
void decReference()
|
||||
{
|
||||
if(!--m_refs)
|
||||
delete this;
|
||||
}
|
||||
private:
|
||||
ACE_Atomic_Op<ACE_Thread_Mutex, long> m_refs;
|
||||
};
|
||||
|
||||
enum Priority
|
||||
{
|
||||
Idle,
|
||||
Lowest,
|
||||
Low,
|
||||
Normal,
|
||||
High,
|
||||
Highest,
|
||||
Realtime,
|
||||
};
|
||||
|
||||
#define MAXPRIORITYNUM (Realtime + 1)
|
||||
|
||||
class ThreadPriority
|
||||
{
|
||||
public:
|
||||
ThreadPriority();
|
||||
int getPriority(Priority p) const;
|
||||
|
||||
private:
|
||||
int m_priority[MAXPRIORITYNUM];
|
||||
};
|
||||
|
||||
class Thread
|
||||
{
|
||||
public:
|
||||
Thread();
|
||||
explicit Thread(Runnable* instance);
|
||||
~Thread();
|
||||
|
||||
bool start();
|
||||
bool wait();
|
||||
void destroy();
|
||||
|
||||
void suspend();
|
||||
void resume();
|
||||
|
||||
void setPriority(Priority type);
|
||||
|
||||
static void Sleep(unsigned long msecs);
|
||||
static ACE_thread_t currentId();
|
||||
static ACE_hthread_t currentHandle();
|
||||
static Thread * current();
|
||||
|
||||
private:
|
||||
Thread(const Thread&);
|
||||
Thread& operator=(const Thread&);
|
||||
|
||||
static ACE_THR_FUNC_RETURN ThreadTask(void * param);
|
||||
|
||||
ACE_thread_t m_iThreadId;
|
||||
ACE_hthread_t m_hThreadHandle;
|
||||
Runnable * m_task;
|
||||
|
||||
typedef ACE_TSS<Thread> ThreadStorage;
|
||||
//global object - container for Thread class representation of every thread
|
||||
static ThreadStorage m_ThreadStorage;
|
||||
//use this object to determine current OS thread priority values mapped to enum Priority{}
|
||||
static ThreadPriority m_TpEnum;
|
||||
};
|
||||
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,215 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
|
||||
*
|
||||
* Copyright (C) 2008-2010 Trinity <http://www.trinitycore.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; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public 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 TRINITY_TIMER_H
|
||||
#define TRINITY_TIMER_H
|
||||
|
||||
#include "Platform/CompilerDefs.h"
|
||||
|
||||
#if PLATFORM == PLATFORM_WINDOWS
|
||||
# include <ace/config-all.h>
|
||||
# include <mmsystem.h>
|
||||
# include <time.h>
|
||||
#else
|
||||
# if defined(__APPLE_CC__)
|
||||
# include <time.h>
|
||||
# endif
|
||||
# include <sys/time.h>
|
||||
# include <sys/timeb.h>
|
||||
#endif
|
||||
|
||||
#if PLATFORM == PLATFORM_WINDOWS
|
||||
inline uint32 getMSTime() { return GetTickCount(); }
|
||||
#else
|
||||
inline uint32 getMSTime()
|
||||
{
|
||||
struct timeval tv;
|
||||
struct timezone tz;
|
||||
gettimeofday( &tv, &tz );
|
||||
return (tv.tv_sec * 1000) + (tv.tv_usec / 1000);
|
||||
}
|
||||
#endif
|
||||
|
||||
inline uint32 getMSTimeDiff(uint32 oldMSTime, uint32 newMSTime)
|
||||
{
|
||||
// getMSTime() have limited data range and this is case when it overflow in this tick
|
||||
if (oldMSTime > newMSTime)
|
||||
return (0xFFFFFFFF - oldMSTime) + newMSTime;
|
||||
else
|
||||
return newMSTime - oldMSTime;
|
||||
}
|
||||
|
||||
struct IntervalTimer
|
||||
{
|
||||
public:
|
||||
|
||||
IntervalTimer()
|
||||
: _interval(0), _current(0)
|
||||
{
|
||||
}
|
||||
|
||||
void Update(time_t diff)
|
||||
{
|
||||
_current += diff;
|
||||
if (_current < 0)
|
||||
_current = 0;
|
||||
}
|
||||
|
||||
bool Passed()
|
||||
{
|
||||
return _current >= _interval;
|
||||
}
|
||||
|
||||
void Reset()
|
||||
{
|
||||
if (_current >= _interval)
|
||||
_current -= _interval;
|
||||
}
|
||||
|
||||
void SetCurrent(time_t current)
|
||||
{
|
||||
_current = current;
|
||||
}
|
||||
|
||||
void SetInterval(time_t interval)
|
||||
{
|
||||
_interval = interval;
|
||||
}
|
||||
|
||||
time_t GetInterval() const
|
||||
{
|
||||
return _interval;
|
||||
}
|
||||
|
||||
time_t GetCurrent() const
|
||||
{
|
||||
return _current;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
time_t _interval;
|
||||
time_t _current;
|
||||
};
|
||||
|
||||
struct TimeTracker
|
||||
{
|
||||
public:
|
||||
|
||||
TimeTracker(time_t expiry)
|
||||
: i_expiryTime(expiry)
|
||||
{
|
||||
}
|
||||
|
||||
void Update(time_t diff)
|
||||
{
|
||||
i_expiryTime -= diff;
|
||||
}
|
||||
|
||||
bool Passed() const
|
||||
{
|
||||
return i_expiryTime <= 0;
|
||||
}
|
||||
|
||||
void Reset(time_t interval)
|
||||
{
|
||||
i_expiryTime = interval;
|
||||
}
|
||||
|
||||
time_t GetExpiry() const
|
||||
{
|
||||
return i_expiryTime;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
time_t i_expiryTime;
|
||||
};
|
||||
|
||||
struct TimeTrackerSmall
|
||||
{
|
||||
public:
|
||||
|
||||
TimeTrackerSmall(uint32 expiry)
|
||||
: i_expiryTime(expiry)
|
||||
{
|
||||
}
|
||||
|
||||
void Update(int32 diff)
|
||||
{
|
||||
i_expiryTime -= diff;
|
||||
}
|
||||
|
||||
bool Passed() const
|
||||
{
|
||||
return i_expiryTime <= 0;
|
||||
}
|
||||
|
||||
void Reset(uint32 interval)
|
||||
{
|
||||
i_expiryTime = interval;
|
||||
}
|
||||
|
||||
int32 GetExpiry() const
|
||||
{
|
||||
return i_expiryTime;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
int32 i_expiryTime;
|
||||
};
|
||||
|
||||
struct PeriodicTimer
|
||||
{
|
||||
public:
|
||||
|
||||
PeriodicTimer(int32 period, int32 start_time)
|
||||
: i_expireTime(start_time), i_period(period)
|
||||
{
|
||||
}
|
||||
|
||||
bool Update(const uint32 &diff)
|
||||
{
|
||||
if ((i_expireTime -= diff) > 0)
|
||||
return false;
|
||||
|
||||
i_expireTime += i_period > diff ? i_period : diff;
|
||||
return true;
|
||||
}
|
||||
|
||||
void SetPeriodic(int32 period, int32 start_time)
|
||||
{
|
||||
i_expireTime = start_time;
|
||||
i_period = period;
|
||||
}
|
||||
|
||||
// Tracker interface
|
||||
void TUpdate(int32 diff) { i_expireTime -= diff; }
|
||||
bool TPassed() const { return i_expireTime <= 0; }
|
||||
void TReset(int32 diff, int32 period) { i_expireTime += period > diff ? period : diff; }
|
||||
|
||||
private:
|
||||
|
||||
int32 i_period;
|
||||
int32 i_expireTime;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,468 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
|
||||
*
|
||||
* Copyright (C) 2008-2010 Trinity <http://www.trinitycore.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; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public 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 "Util.h"
|
||||
|
||||
#include "sockets/socket_include.h"
|
||||
#include "utf8cpp/utf8.h"
|
||||
#include "mersennetwister/MersenneTwister.h"
|
||||
#include <ace/TSS_T.h>
|
||||
|
||||
typedef ACE_TSS<MTRand> MTRandTSS;
|
||||
static MTRandTSS mtRand;
|
||||
|
||||
int32 irand (int32 min, int32 max)
|
||||
{
|
||||
return int32 (mtRand->randInt (max - min)) + min;
|
||||
}
|
||||
|
||||
uint32 urand (uint32 min, uint32 max)
|
||||
{
|
||||
return mtRand->randInt (max - min) + min;
|
||||
}
|
||||
|
||||
int32 rand32 ()
|
||||
{
|
||||
return mtRand->randInt ();
|
||||
}
|
||||
|
||||
double rand_norm(void)
|
||||
{
|
||||
return mtRand->randExc ();
|
||||
}
|
||||
|
||||
double rand_chance (void)
|
||||
{
|
||||
return mtRand->randExc (100.0);
|
||||
}
|
||||
|
||||
Tokens StrSplit(const std::string &src, const std::string &sep)
|
||||
{
|
||||
Tokens r;
|
||||
std::string s;
|
||||
for (std::string::const_iterator i = src.begin(); i != src.end(); i++)
|
||||
{
|
||||
if (sep.find(*i) != std::string::npos)
|
||||
{
|
||||
if (s.length()) r.push_back(s);
|
||||
s = "";
|
||||
}
|
||||
else
|
||||
{
|
||||
s += *i;
|
||||
}
|
||||
}
|
||||
if (s.length()) r.push_back(s);
|
||||
return r;
|
||||
}
|
||||
|
||||
void stripLineInvisibleChars(std::string &str)
|
||||
{
|
||||
static std::string invChars = " \t\7\n";
|
||||
|
||||
size_t wpos = 0;
|
||||
|
||||
bool space = false;
|
||||
for (size_t pos = 0; pos < str.size(); ++pos)
|
||||
{
|
||||
if(invChars.find(str[pos])!=std::string::npos)
|
||||
{
|
||||
if(!space)
|
||||
{
|
||||
str[wpos++] = ' ';
|
||||
space = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if(wpos!=pos)
|
||||
str[wpos++] = str[pos];
|
||||
else
|
||||
++wpos;
|
||||
space = false;
|
||||
}
|
||||
}
|
||||
|
||||
if(wpos < str.size())
|
||||
str.erase(wpos,str.size());
|
||||
if(str.find("|TInterface")!=std::string::npos)
|
||||
str.clear();
|
||||
|
||||
}
|
||||
|
||||
std::string secsToTimeString(uint32 timeInSecs, bool shortText, bool hoursOnly)
|
||||
{
|
||||
uint32 secs = timeInSecs % MINUTE;
|
||||
uint32 minutes = timeInSecs % HOUR / MINUTE;
|
||||
uint32 hours = timeInSecs % DAY / HOUR;
|
||||
uint32 days = timeInSecs / DAY;
|
||||
|
||||
std::ostringstream ss;
|
||||
if(days)
|
||||
ss << days << (shortText ? "d" : " Day(s) ");
|
||||
if(hours || hoursOnly)
|
||||
ss << hours << (shortText ? "h" : " Hour(s) ");
|
||||
if(!hoursOnly)
|
||||
{
|
||||
if(minutes)
|
||||
ss << minutes << (shortText ? "m" : " Minute(s) ");
|
||||
if(secs || (!days && !hours && !minutes) )
|
||||
ss << secs << (shortText ? "s" : " Second(s).");
|
||||
}
|
||||
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
uint32 TimeStringToSecs(const std::string& timestring)
|
||||
{
|
||||
uint32 secs = 0;
|
||||
uint32 buffer = 0;
|
||||
uint32 multiplier = 0;
|
||||
|
||||
for (std::string::const_iterator itr = timestring.begin(); itr != timestring.end(); itr++ )
|
||||
{
|
||||
if(isdigit(*itr))
|
||||
{
|
||||
buffer*=10;
|
||||
buffer+= (*itr)-'0';
|
||||
}
|
||||
else
|
||||
{
|
||||
switch(*itr)
|
||||
{
|
||||
case 'd': multiplier = DAY; break;
|
||||
case 'h': multiplier = HOUR; break;
|
||||
case 'm': multiplier = MINUTE; break;
|
||||
case 's': multiplier = 1; break;
|
||||
default : return 0; //bad format
|
||||
}
|
||||
buffer*=multiplier;
|
||||
secs+=buffer;
|
||||
buffer=0;
|
||||
}
|
||||
}
|
||||
|
||||
return secs;
|
||||
}
|
||||
|
||||
std::string TimeToTimestampStr(time_t t)
|
||||
{
|
||||
tm* aTm = localtime(&t);
|
||||
// YYYY year
|
||||
// MM month (2 digits 01-12)
|
||||
// DD day (2 digits 01-31)
|
||||
// HH hour (2 digits 00-23)
|
||||
// MM minutes (2 digits 00-59)
|
||||
// SS seconds (2 digits 00-59)
|
||||
char buf[20];
|
||||
snprintf(buf,20,"%04d-%02d-%02d_%02d-%02d-%02d",aTm->tm_year+1900,aTm->tm_mon+1,aTm->tm_mday,aTm->tm_hour,aTm->tm_min,aTm->tm_sec);
|
||||
return std::string(buf);
|
||||
}
|
||||
|
||||
/// Check if the string is a valid ip address representation
|
||||
bool IsIPAddress(char const* ipaddress)
|
||||
{
|
||||
if(!ipaddress)
|
||||
return false;
|
||||
|
||||
// Let the big boys do it.
|
||||
// Drawback: all valid ip address formats are recognized e.g.: 12.23,121234,0xABCD)
|
||||
return inet_addr(ipaddress) != INADDR_NONE;
|
||||
}
|
||||
|
||||
/// create PID file
|
||||
uint32 CreatePIDFile(const std::string& filename)
|
||||
{
|
||||
FILE * pid_file = fopen (filename.c_str(), "w" );
|
||||
if (pid_file == NULL)
|
||||
return 0;
|
||||
|
||||
#ifdef WIN32
|
||||
DWORD pid = GetCurrentProcessId();
|
||||
#else
|
||||
pid_t pid = getpid();
|
||||
#endif
|
||||
|
||||
fprintf(pid_file, "%d", pid );
|
||||
fclose(pid_file);
|
||||
|
||||
return (uint32)pid;
|
||||
}
|
||||
|
||||
size_t utf8length(std::string& utf8str)
|
||||
{
|
||||
try
|
||||
{
|
||||
return utf8::distance(utf8str.c_str(),utf8str.c_str()+utf8str.size());
|
||||
}
|
||||
catch(std::exception)
|
||||
{
|
||||
utf8str = "";
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
void utf8truncate(std::string& utf8str,size_t len)
|
||||
{
|
||||
try
|
||||
{
|
||||
size_t wlen = utf8::distance(utf8str.c_str(),utf8str.c_str()+utf8str.size());
|
||||
if(wlen <= len)
|
||||
return;
|
||||
|
||||
std::wstring wstr;
|
||||
wstr.resize(wlen);
|
||||
utf8::utf8to16(utf8str.c_str(),utf8str.c_str()+utf8str.size(),&wstr[0]);
|
||||
wstr.resize(len);
|
||||
char* oend = utf8::utf16to8(wstr.c_str(),wstr.c_str()+wstr.size(),&utf8str[0]);
|
||||
utf8str.resize(oend-(&utf8str[0])); // remove unused tail
|
||||
}
|
||||
catch(std::exception)
|
||||
{
|
||||
utf8str = "";
|
||||
}
|
||||
}
|
||||
|
||||
bool Utf8toWStr(char const* utf8str, size_t csize, wchar_t* wstr, size_t& wsize)
|
||||
{
|
||||
try
|
||||
{
|
||||
size_t len = utf8::distance(utf8str,utf8str+csize);
|
||||
if(len > wsize)
|
||||
{
|
||||
if(wsize > 0)
|
||||
wstr[0] = L'\0';
|
||||
wsize = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
wsize = len;
|
||||
utf8::utf8to16(utf8str,utf8str+csize,wstr);
|
||||
wstr[len] = L'\0';
|
||||
}
|
||||
catch(std::exception)
|
||||
{
|
||||
if(wsize > 0)
|
||||
wstr[0] = L'\0';
|
||||
wsize = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Utf8toWStr(const std::string& utf8str, std::wstring& wstr)
|
||||
{
|
||||
try
|
||||
{
|
||||
size_t len = utf8::distance(utf8str.c_str(),utf8str.c_str()+utf8str.size());
|
||||
wstr.resize(len);
|
||||
|
||||
utf8::utf8to16(utf8str.c_str(),utf8str.c_str()+utf8str.size(),&wstr[0]);
|
||||
}
|
||||
catch(std::exception)
|
||||
{
|
||||
wstr = L"";
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool WStrToUtf8(wchar_t* wstr, size_t size, std::string& utf8str)
|
||||
{
|
||||
try
|
||||
{
|
||||
std::string utf8str2;
|
||||
utf8str2.resize(size*4); // allocate for most long case
|
||||
|
||||
char* oend = utf8::utf16to8(wstr,wstr+size,&utf8str2[0]);
|
||||
utf8str2.resize(oend-(&utf8str2[0])); // remove unused tail
|
||||
utf8str = utf8str2;
|
||||
}
|
||||
catch(std::exception)
|
||||
{
|
||||
utf8str = "";
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool WStrToUtf8(std::wstring wstr, std::string& utf8str)
|
||||
{
|
||||
try
|
||||
{
|
||||
std::string utf8str2;
|
||||
utf8str2.resize(wstr.size()*4); // allocate for most long case
|
||||
|
||||
char* oend = utf8::utf16to8(wstr.c_str(),wstr.c_str()+wstr.size(),&utf8str2[0]);
|
||||
utf8str2.resize(oend-(&utf8str2[0])); // remove unused tail
|
||||
utf8str = utf8str2;
|
||||
}
|
||||
catch(std::exception)
|
||||
{
|
||||
utf8str = "";
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
typedef wchar_t const* const* wstrlist;
|
||||
|
||||
std::wstring GetMainPartOfName(std::wstring wname, uint32 declension)
|
||||
{
|
||||
// supported only Cyrillic cases
|
||||
if(wname.size() < 1 || !isCyrillicCharacter(wname[0]) || declension > 5)
|
||||
return wname;
|
||||
|
||||
// Important: end length must be <= MAX_INTERNAL_PLAYER_NAME-MAX_PLAYER_NAME (3 currently)
|
||||
|
||||
static wchar_t const a_End[] = { wchar_t(1), wchar_t(0x0430),wchar_t(0x0000)};
|
||||
static wchar_t const o_End[] = { wchar_t(1), wchar_t(0x043E),wchar_t(0x0000)};
|
||||
static wchar_t const ya_End[] = { wchar_t(1), wchar_t(0x044F),wchar_t(0x0000)};
|
||||
static wchar_t const ie_End[] = { wchar_t(1), wchar_t(0x0435),wchar_t(0x0000)};
|
||||
static wchar_t const i_End[] = { wchar_t(1), wchar_t(0x0438),wchar_t(0x0000)};
|
||||
static wchar_t const yeru_End[] = { wchar_t(1), wchar_t(0x044B),wchar_t(0x0000)};
|
||||
static wchar_t const u_End[] = { wchar_t(1), wchar_t(0x0443),wchar_t(0x0000)};
|
||||
static wchar_t const yu_End[] = { wchar_t(1), wchar_t(0x044E),wchar_t(0x0000)};
|
||||
static wchar_t const oj_End[] = { wchar_t(2), wchar_t(0x043E),wchar_t(0x0439),wchar_t(0x0000)};
|
||||
static wchar_t const ie_j_End[] = { wchar_t(2), wchar_t(0x0435),wchar_t(0x0439),wchar_t(0x0000)};
|
||||
static wchar_t const io_j_End[] = { wchar_t(2), wchar_t(0x0451),wchar_t(0x0439),wchar_t(0x0000)};
|
||||
static wchar_t const o_m_End[] = { wchar_t(2), wchar_t(0x043E),wchar_t(0x043C),wchar_t(0x0000)};
|
||||
static wchar_t const io_m_End[] = { wchar_t(2), wchar_t(0x0451),wchar_t(0x043C),wchar_t(0x0000)};
|
||||
static wchar_t const ie_m_End[] = { wchar_t(2), wchar_t(0x0435),wchar_t(0x043C),wchar_t(0x0000)};
|
||||
static wchar_t const soft_End[] = { wchar_t(1), wchar_t(0x044C),wchar_t(0x0000)};
|
||||
static wchar_t const j_End[] = { wchar_t(1), wchar_t(0x0439),wchar_t(0x0000)};
|
||||
|
||||
static wchar_t const* const dropEnds[6][8] = {
|
||||
{ &a_End[1], &o_End[1], &ya_End[1], &ie_End[1], &soft_End[1], &j_End[1], NULL, NULL },
|
||||
{ &a_End[1], &ya_End[1], &yeru_End[1], &i_End[1], NULL, NULL, NULL, NULL },
|
||||
{ &ie_End[1], &u_End[1], &yu_End[1], &i_End[1], NULL, NULL, NULL, NULL },
|
||||
{ &u_End[1], &yu_End[1], &o_End[1], &ie_End[1], &soft_End[1], &ya_End[1], &a_End[1], NULL },
|
||||
{ &oj_End[1], &io_j_End[1], &ie_j_End[1], &o_m_End[1], &io_m_End[1], &ie_m_End[1], &yu_End[1], NULL },
|
||||
{ &ie_End[1], &i_End[1], NULL, NULL, NULL, NULL, NULL, NULL }
|
||||
};
|
||||
|
||||
for (wchar_t const * const* itr = &dropEnds[declension][0]; *itr; ++itr)
|
||||
{
|
||||
size_t len = size_t((*itr)[-1]); // get length from string size field
|
||||
|
||||
if(wname.substr(wname.size()-len,len)==*itr)
|
||||
return wname.substr(0,wname.size()-len);
|
||||
}
|
||||
|
||||
return wname;
|
||||
}
|
||||
|
||||
bool utf8ToConsole(const std::string& utf8str, std::string& conStr)
|
||||
{
|
||||
#if PLATFORM == PLATFORM_WINDOWS
|
||||
std::wstring wstr;
|
||||
if(!Utf8toWStr(utf8str,wstr))
|
||||
return false;
|
||||
|
||||
conStr.resize(wstr.size());
|
||||
CharToOemBuffW(&wstr[0],&conStr[0],wstr.size());
|
||||
#else
|
||||
// not implemented yet
|
||||
conStr = utf8str;
|
||||
#endif
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool consoleToUtf8(const std::string& conStr,std::string& utf8str)
|
||||
{
|
||||
#if PLATFORM == PLATFORM_WINDOWS
|
||||
std::wstring wstr;
|
||||
wstr.resize(conStr.size());
|
||||
OemToCharBuffW(&conStr[0],&wstr[0],conStr.size());
|
||||
|
||||
return WStrToUtf8(wstr,utf8str);
|
||||
#else
|
||||
// not implemented yet
|
||||
utf8str = conStr;
|
||||
return true;
|
||||
#endif
|
||||
}
|
||||
|
||||
bool Utf8FitTo(const std::string& str, std::wstring search)
|
||||
{
|
||||
std::wstring temp;
|
||||
|
||||
if(!Utf8toWStr(str,temp))
|
||||
return false;
|
||||
|
||||
// converting to lower case
|
||||
wstrToLower( temp );
|
||||
|
||||
if(temp.find(search) == std::wstring::npos)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void utf8printf(FILE *out, const char *str, ...)
|
||||
{
|
||||
va_list ap;
|
||||
va_start(ap, str);
|
||||
vutf8printf(out, str, &ap);
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
void vutf8printf(FILE *out, const char *str, va_list* ap)
|
||||
{
|
||||
#if PLATFORM == PLATFORM_WINDOWS
|
||||
char temp_buf[32*1024];
|
||||
wchar_t wtemp_buf[32*1024];
|
||||
|
||||
size_t temp_len = vsnprintf(temp_buf, 32*1024, str, *ap);
|
||||
|
||||
size_t wtemp_len = 32*1024-1;
|
||||
Utf8toWStr(temp_buf, temp_len, wtemp_buf, wtemp_len);
|
||||
|
||||
CharToOemBuffW(&wtemp_buf[0], &temp_buf[0], wtemp_len+1);
|
||||
fprintf(out, temp_buf);
|
||||
#else
|
||||
vfprintf(out, str, *ap);
|
||||
#endif
|
||||
}
|
||||
|
||||
void hexEncodeByteArray(uint8* bytes, uint32 arrayLen, std::string& result)
|
||||
{
|
||||
std::ostringstream ss;
|
||||
for (uint32 i=0; i<arrayLen; ++i)
|
||||
{
|
||||
for (uint8 j=0; j<2; ++j)
|
||||
{
|
||||
unsigned char nibble = 0x0F & (bytes[i]>>((1-j)*4));
|
||||
char encodedNibble;
|
||||
if(nibble < 0x0A)
|
||||
encodedNibble = '0'+nibble;
|
||||
else
|
||||
encodedNibble = 'A'+nibble-0x0A;
|
||||
ss << encodedNibble;
|
||||
}
|
||||
}
|
||||
result = ss.str();
|
||||
}
|
||||
|
||||
@@ -0,0 +1,536 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
|
||||
*
|
||||
* Copyright (C) 2008-2010 Trinity <http://www.trinitycore.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; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public 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 _UTIL_H
|
||||
#define _UTIL_H
|
||||
|
||||
#include "Common.h"
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
typedef std::vector<std::string> Tokens;
|
||||
|
||||
Tokens StrSplit(const std::string &src, const std::string &sep);
|
||||
|
||||
void stripLineInvisibleChars(std::string &src);
|
||||
|
||||
std::string secsToTimeString(uint32 timeInSecs, bool shortText = false, bool hoursOnly = false);
|
||||
uint32 TimeStringToSecs(const std::string& timestring);
|
||||
std::string TimeToTimestampStr(time_t t);
|
||||
|
||||
inline uint32 secsToTimeBitFields(time_t secs)
|
||||
{
|
||||
tm* lt = localtime(&secs);
|
||||
return (lt->tm_year - 100) << 24 | lt->tm_mon << 20 | (lt->tm_mday - 1) << 14 | lt->tm_wday << 11 | lt->tm_hour << 6 | lt->tm_min;
|
||||
}
|
||||
|
||||
/* Return a random number in the range min..max; (max-min) must be smaller than 32768. */
|
||||
int32 irand(int32 min, int32 max);
|
||||
|
||||
/* Return a random number in the range min..max (inclusive). For reliable results, the difference
|
||||
* between max and min should be less than RAND32_MAX. */
|
||||
uint32 urand(uint32 min, uint32 max);
|
||||
|
||||
/* Return a random number in the range 0 .. RAND32_MAX. */
|
||||
int32 rand32();
|
||||
|
||||
/* Return a random double from 0.0 to 1.0 (exclusive). Floats support only 7 valid decimal digits.
|
||||
* A double supports up to 15 valid decimal digits and is used internally (RAND32_MAX has 10 digits).
|
||||
* With an FPU, there is usually no difference in performance between float and double. */
|
||||
double rand_norm(void);
|
||||
|
||||
/* Return a random double from 0.0 to 99.9999999999999. Floats support only 7 valid decimal digits.
|
||||
* A double supports up to 15 valid decimal digits and is used internaly (RAND32_MAX has 10 digits).
|
||||
* With an FPU, there is usually no difference in performance between float and double. */
|
||||
double rand_chance(void);
|
||||
|
||||
/* Return true if a random roll fits in the specified chance (range 0-100). */
|
||||
inline bool roll_chance_f(float chance)
|
||||
{
|
||||
return chance > rand_chance();
|
||||
}
|
||||
|
||||
/* Return true if a random roll fits in the specified chance (range 0-100). */
|
||||
inline bool roll_chance_i(int chance)
|
||||
{
|
||||
return chance > irand(0, 99);
|
||||
}
|
||||
|
||||
inline void ApplyModUInt32Var(uint32& var, int32 val, bool apply)
|
||||
{
|
||||
int32 cur = var;
|
||||
cur += (apply ? val : -val);
|
||||
if(cur < 0)
|
||||
cur = 0;
|
||||
var = cur;
|
||||
}
|
||||
|
||||
inline void ApplyModFloatVar(float& var, float val, bool apply)
|
||||
{
|
||||
var += (apply ? val : -val);
|
||||
if(var < 0)
|
||||
var = 0;
|
||||
}
|
||||
|
||||
inline void ApplyPercentModFloatVar(float& var, float val, bool apply)
|
||||
{
|
||||
if (val == -100.0f) // prevent set var to zero
|
||||
val = -99.99f;
|
||||
var *= (apply?(100.0f+val)/100.0f : 100.0f / (100.0f+val));
|
||||
}
|
||||
|
||||
bool Utf8toWStr(const std::string& utf8str, std::wstring& wstr);
|
||||
// in wsize==max size of buffer, out wsize==real string size
|
||||
bool Utf8toWStr(char const* utf8str, size_t csize, wchar_t* wstr, size_t& wsize);
|
||||
inline bool Utf8toWStr(const std::string& utf8str, wchar_t* wstr, size_t& wsize)
|
||||
{
|
||||
return Utf8toWStr(utf8str.c_str(), utf8str.size(), wstr, wsize);
|
||||
}
|
||||
|
||||
bool WStrToUtf8(std::wstring wstr, std::string& utf8str);
|
||||
// size==real string size
|
||||
bool WStrToUtf8(wchar_t* wstr, size_t size, std::string& utf8str);
|
||||
|
||||
size_t utf8length(std::string& utf8str); // set string to "" if invalid utf8 sequence
|
||||
void utf8truncate(std::string& utf8str,size_t len);
|
||||
|
||||
inline bool isBasicLatinCharacter(wchar_t wchar)
|
||||
{
|
||||
if(wchar >= L'a' && wchar <= L'z') // LATIN SMALL LETTER A - LATIN SMALL LETTER Z
|
||||
return true;
|
||||
if(wchar >= L'A' && wchar <= L'Z') // LATIN CAPITAL LETTER A - LATIN CAPITAL LETTER Z
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
inline bool isExtendedLatinCharacter(wchar_t wchar)
|
||||
{
|
||||
if(isBasicLatinCharacter(wchar))
|
||||
return true;
|
||||
if(wchar >= 0x00C0 && wchar <= 0x00D6) // LATIN CAPITAL LETTER A WITH GRAVE - LATIN CAPITAL LETTER O WITH DIAERESIS
|
||||
return true;
|
||||
if(wchar >= 0x00D8 && wchar <= 0x00DF) // LATIN CAPITAL LETTER O WITH STROKE - LATIN CAPITAL LETTER THORN
|
||||
return true;
|
||||
if(wchar == 0x00DF) // LATIN SMALL LETTER SHARP S
|
||||
return true;
|
||||
if(wchar >= 0x00E0 && wchar <= 0x00F6) // LATIN SMALL LETTER A WITH GRAVE - LATIN SMALL LETTER O WITH DIAERESIS
|
||||
return true;
|
||||
if(wchar >= 0x00F8 && wchar <= 0x00FE) // LATIN SMALL LETTER O WITH STROKE - LATIN SMALL LETTER THORN
|
||||
return true;
|
||||
if(wchar >= 0x0100 && wchar <= 0x012F) // LATIN CAPITAL LETTER A WITH MACRON - LATIN SMALL LETTER I WITH OGONEK
|
||||
return true;
|
||||
if(wchar == 0x1E9E) // LATIN CAPITAL LETTER SHARP S
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
inline bool isCyrillicCharacter(wchar_t wchar)
|
||||
{
|
||||
if(wchar >= 0x0410 && wchar <= 0x044F) // CYRILLIC CAPITAL LETTER A - CYRILLIC SMALL LETTER YA
|
||||
return true;
|
||||
if(wchar == 0x0401 || wchar == 0x0451) // CYRILLIC CAPITAL LETTER IO, CYRILLIC SMALL LETTER IO
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
inline bool isEastAsianCharacter(wchar_t wchar)
|
||||
{
|
||||
if(wchar >= 0x1100 && wchar <= 0x11F9) // Hangul Jamo
|
||||
return true;
|
||||
if(wchar >= 0x3041 && wchar <= 0x30FF) // Hiragana + Katakana
|
||||
return true;
|
||||
if(wchar >= 0x3131 && wchar <= 0x318E) // Hangul Compatibility Jamo
|
||||
return true;
|
||||
if(wchar >= 0x31F0 && wchar <= 0x31FF) // Katakana Phonetic Ext.
|
||||
return true;
|
||||
if(wchar >= 0x3400 && wchar <= 0x4DB5) // CJK Ideographs Ext. A
|
||||
return true;
|
||||
if(wchar >= 0x4E00 && wchar <= 0x9FC3) // Unified CJK Ideographs
|
||||
return true;
|
||||
if(wchar >= 0xAC00 && wchar <= 0xD7A3) // Hangul Syllables
|
||||
return true;
|
||||
if(wchar >= 0xFF01 && wchar <= 0xFFEE) // Halfwidth forms
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
inline bool isNumeric(wchar_t wchar)
|
||||
{
|
||||
return (wchar >= L'0' && wchar <=L'9');
|
||||
}
|
||||
|
||||
inline bool isNumeric(char c)
|
||||
{
|
||||
return (c >= '0' && c <='9');
|
||||
}
|
||||
|
||||
inline bool isNumericOrSpace(wchar_t wchar)
|
||||
{
|
||||
return isNumeric(wchar) || wchar == L' ';
|
||||
}
|
||||
|
||||
inline bool isBasicLatinString(std::wstring wstr, bool numericOrSpace)
|
||||
{
|
||||
for (size_t i = 0; i < wstr.size(); ++i)
|
||||
if(!isBasicLatinCharacter(wstr[i]) && (!numericOrSpace || !isNumericOrSpace(wstr[i])))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
inline bool isExtendedLatinString(std::wstring wstr, bool numericOrSpace)
|
||||
{
|
||||
for (size_t i = 0; i < wstr.size(); ++i)
|
||||
if(!isExtendedLatinCharacter(wstr[i]) && (!numericOrSpace || !isNumericOrSpace(wstr[i])))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
inline bool isCyrillicString(std::wstring wstr, bool numericOrSpace)
|
||||
{
|
||||
for (size_t i = 0; i < wstr.size(); ++i)
|
||||
if(!isCyrillicCharacter(wstr[i]) && (!numericOrSpace || !isNumericOrSpace(wstr[i])))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
inline bool isEastAsianString(std::wstring wstr, bool numericOrSpace)
|
||||
{
|
||||
for (size_t i = 0; i < wstr.size(); ++i)
|
||||
if(!isEastAsianCharacter(wstr[i]) && (!numericOrSpace || !isNumericOrSpace(wstr[i])))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
inline wchar_t wcharToUpper(wchar_t wchar)
|
||||
{
|
||||
if(wchar >= L'a' && wchar <= L'z') // LATIN SMALL LETTER A - LATIN SMALL LETTER Z
|
||||
return wchar_t(uint16(wchar)-0x0020);
|
||||
if(wchar == 0x00DF) // LATIN SMALL LETTER SHARP S
|
||||
return wchar_t(0x1E9E);
|
||||
if(wchar >= 0x00E0 && wchar <= 0x00F6) // LATIN SMALL LETTER A WITH GRAVE - LATIN SMALL LETTER O WITH DIAERESIS
|
||||
return wchar_t(uint16(wchar)-0x0020);
|
||||
if(wchar >= 0x00F8 && wchar <= 0x00FE) // LATIN SMALL LETTER O WITH STROKE - LATIN SMALL LETTER THORN
|
||||
return wchar_t(uint16(wchar)-0x0020);
|
||||
if(wchar >= 0x0101 && wchar <= 0x012F) // LATIN SMALL LETTER A WITH MACRON - LATIN SMALL LETTER I WITH OGONEK (only %2=1)
|
||||
{
|
||||
if(wchar % 2 == 1)
|
||||
return wchar_t(uint16(wchar)-0x0001);
|
||||
}
|
||||
if(wchar >= 0x0430 && wchar <= 0x044F) // CYRILLIC SMALL LETTER A - CYRILLIC SMALL LETTER YA
|
||||
return wchar_t(uint16(wchar)-0x0020);
|
||||
if(wchar == 0x0451) // CYRILLIC SMALL LETTER IO
|
||||
return wchar_t(0x0401);
|
||||
|
||||
return wchar;
|
||||
}
|
||||
|
||||
inline wchar_t wcharToUpperOnlyLatin(wchar_t wchar)
|
||||
{
|
||||
return isBasicLatinCharacter(wchar) ? wcharToUpper(wchar) : wchar;
|
||||
}
|
||||
|
||||
inline wchar_t wcharToLower(wchar_t wchar)
|
||||
{
|
||||
if(wchar >= L'A' && wchar <= L'Z') // LATIN CAPITAL LETTER A - LATIN CAPITAL LETTER Z
|
||||
return wchar_t(uint16(wchar)+0x0020);
|
||||
if(wchar >= 0x00C0 && wchar <= 0x00D6) // LATIN CAPITAL LETTER A WITH GRAVE - LATIN CAPITAL LETTER O WITH DIAERESIS
|
||||
return wchar_t(uint16(wchar)+0x0020);
|
||||
if(wchar >= 0x00D8 && wchar <= 0x00DE) // LATIN CAPITAL LETTER O WITH STROKE - LATIN CAPITAL LETTER THORN
|
||||
return wchar_t(uint16(wchar)+0x0020);
|
||||
if(wchar >= 0x0100 && wchar <= 0x012E) // LATIN CAPITAL LETTER A WITH MACRON - LATIN CAPITAL LETTER I WITH OGONEK (only %2=0)
|
||||
{
|
||||
if(wchar % 2 == 0)
|
||||
return wchar_t(uint16(wchar)+0x0001);
|
||||
}
|
||||
if(wchar == 0x1E9E) // LATIN CAPITAL LETTER SHARP S
|
||||
return wchar_t(0x00DF);
|
||||
if(wchar == 0x0401) // CYRILLIC CAPITAL LETTER IO
|
||||
return wchar_t(0x0451);
|
||||
if(wchar >= 0x0410 && wchar <= 0x042F) // CYRILLIC CAPITAL LETTER A - CYRILLIC CAPITAL LETTER YA
|
||||
return wchar_t(uint16(wchar)+0x0020);
|
||||
|
||||
return wchar;
|
||||
}
|
||||
|
||||
inline void wstrToUpper(std::wstring& str)
|
||||
{
|
||||
std::transform( str.begin(), str.end(), str.begin(), wcharToUpper );
|
||||
}
|
||||
|
||||
inline void wstrToLower(std::wstring& str)
|
||||
{
|
||||
std::transform( str.begin(), str.end(), str.begin(), wcharToLower );
|
||||
}
|
||||
|
||||
std::wstring GetMainPartOfName(std::wstring wname, uint32 declension);
|
||||
|
||||
bool utf8ToConsole(const std::string& utf8str, std::string& conStr);
|
||||
bool consoleToUtf8(const std::string& conStr,std::string& utf8str);
|
||||
bool Utf8FitTo(const std::string& str, std::wstring search);
|
||||
void utf8printf(FILE *out, const char *str, ...);
|
||||
void vutf8printf(FILE *out, const char *str, va_list* ap);
|
||||
|
||||
bool IsIPAddress(char const* ipaddress);
|
||||
uint32 CreatePIDFile(const std::string& filename);
|
||||
|
||||
void hexEncodeByteArray(uint8* bytes, uint32 arrayLen, std::string& result);
|
||||
#endif
|
||||
|
||||
//handler for operations on large flags
|
||||
#ifndef _FLAG96
|
||||
#define _FLAG96
|
||||
|
||||
#ifndef PAIR64_HIPART
|
||||
#define PAIR64_HIPART(x) (uint32)((uint64(x) >> 32) & UI64LIT(0x00000000FFFFFFFF))
|
||||
#define PAIR64_LOPART(x) (uint32)(uint64(x) & UI64LIT(0x00000000FFFFFFFF))
|
||||
#endif
|
||||
|
||||
class flag96
|
||||
{
|
||||
private:
|
||||
uint32 part[3];
|
||||
public:
|
||||
flag96(uint32 p1=0,uint32 p2=0,uint32 p3=0)
|
||||
{
|
||||
part[0]=p1;
|
||||
part[1]=p2;
|
||||
part[2]=p3;
|
||||
}
|
||||
|
||||
flag96(uint64 p1, uint32 p2)
|
||||
{
|
||||
part[0]=PAIR64_LOPART(p1);
|
||||
part[1]=PAIR64_HIPART(p1);
|
||||
part[2]=p2;
|
||||
}
|
||||
|
||||
inline bool IsEqual(uint32 p1=0, uint32 p2=0, uint32 p3=0) const
|
||||
{
|
||||
return (
|
||||
part[0]==p1 &&
|
||||
part[1]==p2 &&
|
||||
part[2]==p3);
|
||||
};
|
||||
|
||||
inline bool HasFlag(uint32 p1=0, uint32 p2=0, uint32 p3=0) const
|
||||
{
|
||||
return (
|
||||
part[0]&p1 ||
|
||||
part[1]&p2 ||
|
||||
part[2]&p3);
|
||||
};
|
||||
|
||||
inline void Set(uint32 p1=0, uint32 p2=0, uint32 p3=0)
|
||||
{
|
||||
part[0]=p1;
|
||||
part[1]=p2;
|
||||
part[2]=p3;
|
||||
};
|
||||
|
||||
template<class type>
|
||||
inline bool operator < (type & right)
|
||||
{
|
||||
for (uint8 i=3; i > 0; --i)
|
||||
{
|
||||
if (part[i-1]<right.part[i-1])
|
||||
return 1;
|
||||
else if (part[i-1]>right.part[i-1])
|
||||
return 0;
|
||||
}
|
||||
return 0;
|
||||
};
|
||||
|
||||
template<class type>
|
||||
inline bool operator < (type & right) const
|
||||
{
|
||||
for (uint8 i = 3; i > 0; --i)
|
||||
{
|
||||
if (part[i-1]<right.part[i-1])
|
||||
return 1;
|
||||
else if (part[i-1]>right.part[i-1])
|
||||
return 0;
|
||||
}
|
||||
return 0;
|
||||
};
|
||||
|
||||
template<class type>
|
||||
inline bool operator != (type & right)
|
||||
{
|
||||
if (part[0]!=right.part[0]
|
||||
|| part[1]!=right.part[1]
|
||||
|| part[2]!=right.part[2])
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
template<class type>
|
||||
inline bool operator != (type & right) const
|
||||
{
|
||||
if (part[0]!=right.part[0]
|
||||
|| part[1]!=right.part[1]
|
||||
|| part[2]!=right.part[2])
|
||||
return true;
|
||||
return false;
|
||||
};
|
||||
|
||||
template<class type>
|
||||
inline bool operator == (type & right)
|
||||
{
|
||||
if (part[0]!=right.part[0]
|
||||
|| part[1]!=right.part[1]
|
||||
|| part[2]!=right.part[2])
|
||||
return false;
|
||||
return true;
|
||||
};
|
||||
|
||||
template<class type>
|
||||
inline bool operator == (type & right) const
|
||||
{
|
||||
if (part[0]!=right.part[0]
|
||||
|| part[1]!=right.part[1]
|
||||
|| part[2]!=right.part[2])
|
||||
return false;
|
||||
return true;
|
||||
};
|
||||
|
||||
template<class type>
|
||||
inline void operator = (type & right)
|
||||
{
|
||||
part[0]=right.part[0];
|
||||
part[1]=right.part[1];
|
||||
part[2]=right.part[2];
|
||||
};
|
||||
|
||||
template<class type>
|
||||
inline flag96 operator & (type & right)
|
||||
{
|
||||
flag96 ret(part[0] & right.part[0],part[1] & right.part[1],part[2] & right.part[2]);
|
||||
return
|
||||
ret;
|
||||
};
|
||||
template<class type>
|
||||
inline flag96 operator & (type & right) const
|
||||
{
|
||||
flag96 ret(part[0] & right.part[0],part[1] & right.part[1],part[2] & right.part[2]);
|
||||
return
|
||||
ret;
|
||||
};
|
||||
|
||||
template<class type>
|
||||
inline void operator &= (type & right)
|
||||
{
|
||||
*this=*this & right;
|
||||
};
|
||||
|
||||
template<class type>
|
||||
inline flag96 operator | (type & right)
|
||||
{
|
||||
flag96 ret(part[0] | right.part[0],part[1] | right.part[1],part[2] | right.part[2]);
|
||||
return
|
||||
ret;
|
||||
};
|
||||
|
||||
template<class type>
|
||||
inline flag96 operator | (type & right) const
|
||||
{
|
||||
flag96 ret(part[0] | right.part[0],part[1] | right.part[1],part[2] | right.part[2]);
|
||||
return
|
||||
ret;
|
||||
};
|
||||
|
||||
template<class type>
|
||||
inline void operator |= (type & right)
|
||||
{
|
||||
*this=*this | right;
|
||||
};
|
||||
|
||||
inline void operator ~ ()
|
||||
{
|
||||
part[2]=~part[2];
|
||||
part[1]=~part[1];
|
||||
part[0]=~part[0];
|
||||
};
|
||||
|
||||
template<class type>
|
||||
inline flag96 operator ^ (type & right)
|
||||
{
|
||||
flag96 ret(part[0] ^ right.part[0],part[1] ^ right.part[1],part[2] ^ right.part[2]);
|
||||
return
|
||||
ret;
|
||||
};
|
||||
|
||||
template<class type>
|
||||
inline flag96 operator ^ (type & right) const
|
||||
{
|
||||
flag96 ret(part[0] ^ right.part[0],part[1] ^ right.part[1],part[2] ^ right.part[2]);
|
||||
return
|
||||
ret;
|
||||
};
|
||||
|
||||
template<class type>
|
||||
inline void operator ^= (type & right)
|
||||
{
|
||||
*this=*this^right;
|
||||
};
|
||||
|
||||
inline operator bool() const
|
||||
{
|
||||
return(
|
||||
part[0] != 0 ||
|
||||
part[1] != 0 ||
|
||||
part[2] != 0);
|
||||
};
|
||||
|
||||
inline operator bool()
|
||||
{
|
||||
return(
|
||||
part[0] != 0 ||
|
||||
part[1] != 0 ||
|
||||
part[2] != 0);
|
||||
};
|
||||
|
||||
inline bool operator ! () const
|
||||
{
|
||||
return(
|
||||
part[0] == 0 &&
|
||||
part[1] == 0 &&
|
||||
part[2] == 0);
|
||||
};
|
||||
|
||||
inline bool operator ! ()
|
||||
{
|
||||
return(
|
||||
part[0] == 0 &&
|
||||
part[1] == 0 &&
|
||||
part[2] == 0);
|
||||
};
|
||||
|
||||
inline uint32 & operator[](uint8 el)
|
||||
{
|
||||
return (part[el]);
|
||||
};
|
||||
|
||||
inline const uint32 & operator[](uint8 el) const
|
||||
{
|
||||
return (part[el]);
|
||||
};
|
||||
};
|
||||
#endif
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,118 @@
|
||||
#ifndef _WHEATYEXCEPTIONREPORT_
|
||||
#define _WHEATYEXCEPTIONREPORT_
|
||||
|
||||
#include <dbghelp.h>
|
||||
|
||||
#if _MSC_VER < 1400
|
||||
# define countof(array) (sizeof(array) / sizeof(array[0]))
|
||||
#else
|
||||
# include <stdlib.h>
|
||||
# define countof _countof
|
||||
#endif // _MSC_VER < 1400
|
||||
|
||||
enum BasicType // Stolen from CVCONST.H in the DIA 2.0 SDK
|
||||
{
|
||||
btNoType = 0,
|
||||
btVoid = 1,
|
||||
btChar = 2,
|
||||
btWChar = 3,
|
||||
btInt = 6,
|
||||
btUInt = 7,
|
||||
btFloat = 8,
|
||||
btBCD = 9,
|
||||
btBool = 10,
|
||||
btLong = 13,
|
||||
btULong = 14,
|
||||
btCurrency = 25,
|
||||
btDate = 26,
|
||||
btVariant = 27,
|
||||
btComplex = 28,
|
||||
btBit = 29,
|
||||
btBSTR = 30,
|
||||
btHresult = 31
|
||||
};
|
||||
|
||||
const char* const rgBaseType[] =
|
||||
{
|
||||
" <user defined> ", // btNoType = 0,
|
||||
" void ", // btVoid = 1,
|
||||
" char* ", // btChar = 2,
|
||||
" wchar_t* ", // btWChar = 3,
|
||||
" signed char ",
|
||||
" unsigned char ",
|
||||
" int ", // btInt = 6,
|
||||
" unsigned int ", // btUInt = 7,
|
||||
" float ", // btFloat = 8,
|
||||
" <BCD> ", // btBCD = 9,
|
||||
" bool ", // btBool = 10,
|
||||
" short ",
|
||||
" unsigned short ",
|
||||
" long ", // btLong = 13,
|
||||
" unsigned long ", // btULong = 14,
|
||||
" __int8 ",
|
||||
" __int16 ",
|
||||
" __int32 ",
|
||||
" __int64 ",
|
||||
" __int128 ",
|
||||
" unsigned __int8 ",
|
||||
" unsigned __int16 ",
|
||||
" unsigned __int32 ",
|
||||
" unsigned __int64 ",
|
||||
" unsigned __int128 ",
|
||||
" <currency> ", // btCurrency = 25,
|
||||
" <date> ", // btDate = 26,
|
||||
" VARIANT ", // btVariant = 27,
|
||||
" <complex> ", // btComplex = 28,
|
||||
" <bit> ", // btBit = 29,
|
||||
" BSTR ", // btBSTR = 30,
|
||||
" HRESULT " // btHresult = 31
|
||||
};
|
||||
|
||||
class WheatyExceptionReport
|
||||
{
|
||||
public:
|
||||
|
||||
WheatyExceptionReport();
|
||||
~WheatyExceptionReport();
|
||||
|
||||
// entry point where control comes on an unhandled exception
|
||||
static LONG WINAPI WheatyUnhandledExceptionFilter(
|
||||
PEXCEPTION_POINTERS pExceptionInfo);
|
||||
|
||||
static void printTracesForAllThreads();
|
||||
private:
|
||||
// where report info is extracted and generated
|
||||
static void GenerateExceptionReport(PEXCEPTION_POINTERS pExceptionInfo);
|
||||
static void PrintSystemInfo();
|
||||
static BOOL _GetWindowsVersion(TCHAR* szVersion, DWORD cntMax);
|
||||
static BOOL _GetProcessorName(TCHAR* sProcessorName, DWORD maxcount);
|
||||
|
||||
// Helper functions
|
||||
static LPTSTR GetExceptionString(DWORD dwCode);
|
||||
static BOOL GetLogicalAddress(PVOID addr, PTSTR szModule, DWORD len,
|
||||
DWORD& section, DWORD_PTR& offset);
|
||||
|
||||
static void WriteStackDetails(PCONTEXT pContext, bool bWriteVariables, HANDLE pThreadHandle);
|
||||
|
||||
static BOOL CALLBACK EnumerateSymbolsCallback(PSYMBOL_INFO,ULONG, PVOID);
|
||||
|
||||
static bool FormatSymbolValue(PSYMBOL_INFO, STACKFRAME *, char * pszBuffer, unsigned cbBuffer);
|
||||
|
||||
static char * DumpTypeIndex(char *, DWORD64, DWORD, unsigned, DWORD_PTR, bool & , char*);
|
||||
|
||||
static char * FormatOutputValue(char * pszCurrBuffer, BasicType basicType, DWORD64 length, PVOID pAddress);
|
||||
|
||||
static BasicType GetBasicType(DWORD typeIndex, DWORD64 modBase);
|
||||
|
||||
static int __cdecl _tprintf(const TCHAR * format, ...);
|
||||
|
||||
// Variables used by the class
|
||||
static TCHAR m_szLogFileName[MAX_PATH];
|
||||
static LPTOP_LEVEL_EXCEPTION_FILTER m_previousFilter;
|
||||
static HANDLE m_hReportFile;
|
||||
static HANDLE m_hProcess;
|
||||
};
|
||||
|
||||
extern WheatyExceptionReport g_WheatyExceptionReport; // global instance of class
|
||||
#endif //WheatyExceptionReport
|
||||
|
||||
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
|
||||
*
|
||||
* Copyright (C) 2008-2010 Trinity <http://www.trinitycore.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; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public 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 TRINITYCORE_WORLDPACKET_H
|
||||
#define TRINITYCORE_WORLDPACKET_H
|
||||
|
||||
#include "Common.h"
|
||||
#include "ByteBuffer.h"
|
||||
|
||||
class WorldPacket : public ByteBuffer
|
||||
{
|
||||
public:
|
||||
// just container for later use
|
||||
WorldPacket() : ByteBuffer(0), m_opcode(0)
|
||||
{
|
||||
}
|
||||
explicit WorldPacket(uint16 opcode, size_t res=200) : ByteBuffer(res), m_opcode(opcode) { }
|
||||
// copy constructor
|
||||
WorldPacket(const WorldPacket &packet) : ByteBuffer(packet), m_opcode(packet.m_opcode)
|
||||
{
|
||||
}
|
||||
|
||||
void Initialize(uint16 opcode, size_t newres=200)
|
||||
{
|
||||
clear();
|
||||
_storage.reserve(newres);
|
||||
m_opcode = opcode;
|
||||
}
|
||||
|
||||
uint16 GetOpcode() const { return m_opcode; }
|
||||
void SetOpcode(uint16 opcode) { m_opcode = opcode; }
|
||||
|
||||
protected:
|
||||
uint16 m_opcode;
|
||||
};
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,304 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2010 MaNGOS <http://getmangos.com/>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public 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 "BIH.h"
|
||||
|
||||
void BIH::buildHierarchy(std::vector<uint32> &tempTree, buildData &dat, BuildStats &stats)
|
||||
{
|
||||
// create space for the first node
|
||||
tempTree.push_back(3 << 30); // dummy leaf
|
||||
tempTree.insert(tempTree.end(), 2, 0);
|
||||
//tempTree.add(0);
|
||||
|
||||
// seed bbox
|
||||
AABound gridBox = { bounds.low(), bounds.high() };
|
||||
AABound nodeBox = gridBox;
|
||||
// seed subdivide function
|
||||
subdivide(0, dat.numPrims - 1, tempTree, dat, gridBox, nodeBox, 0, 1, stats);
|
||||
}
|
||||
|
||||
void BIH::subdivide(int left, int right, std::vector<uint32> &tempTree, buildData &dat, AABound &gridBox, AABound &nodeBox, int nodeIndex, int depth, BuildStats &stats)
|
||||
{
|
||||
if ((right - left + 1) <= dat.maxPrims || depth >= MAX_STACK_SIZE)
|
||||
{
|
||||
// write leaf node
|
||||
stats.updateLeaf(depth, right - left + 1);
|
||||
createNode(tempTree, nodeIndex, left, right);
|
||||
return;
|
||||
}
|
||||
// calculate extents
|
||||
int axis = -1, prevAxis, rightOrig;
|
||||
float clipL = G3D::fnan(), clipR = G3D::fnan(), prevClip = G3D::fnan();
|
||||
float split = G3D::fnan(), prevSplit;
|
||||
bool wasLeft = true;
|
||||
while (true)
|
||||
{
|
||||
prevAxis = axis;
|
||||
prevSplit = split;
|
||||
// perform quick consistency checks
|
||||
Vector3 d( gridBox.hi - gridBox.lo );
|
||||
if (d.x < 0 || d.y < 0 || d.z < 0)
|
||||
throw std::logic_error("negative node extents");
|
||||
for (int i = 0; i < 3; i++)
|
||||
{
|
||||
if (nodeBox.hi[i] < gridBox.lo[i] || nodeBox.lo[i] > gridBox.hi[i])
|
||||
{
|
||||
//UI.printError(Module.ACCEL, "Reached tree area in error - discarding node with: %d objects", right - left + 1);
|
||||
throw std::logic_error("invalid node overlap");
|
||||
}
|
||||
}
|
||||
// find longest axis
|
||||
axis = d.primaryAxis();
|
||||
split = 0.5f * (gridBox.lo[axis] + gridBox.hi[axis]);
|
||||
// partition L/R subsets
|
||||
clipL = -G3D::inf();
|
||||
clipR = G3D::inf();
|
||||
rightOrig = right; // save this for later
|
||||
float nodeL = G3D::inf();
|
||||
float nodeR = -G3D::inf();
|
||||
for (int i = left; i <= right;)
|
||||
{
|
||||
int obj = dat.indices[i];
|
||||
float minb = dat.primBound[obj].low()[axis];
|
||||
float maxb = dat.primBound[obj].high()[axis];
|
||||
float center = (minb + maxb) * 0.5f;
|
||||
if (center <= split)
|
||||
{
|
||||
// stay left
|
||||
i++;
|
||||
if (clipL < maxb)
|
||||
clipL = maxb;
|
||||
}
|
||||
else
|
||||
{
|
||||
// move to the right most
|
||||
int t = dat.indices[i];
|
||||
dat.indices[i] = dat.indices[right];
|
||||
dat.indices[right] = t;
|
||||
right--;
|
||||
if (clipR > minb)
|
||||
clipR = minb;
|
||||
}
|
||||
nodeL = std::min(nodeL, minb);
|
||||
nodeR = std::max(nodeR, maxb);
|
||||
}
|
||||
// check for empty space
|
||||
if (nodeL > nodeBox.lo[axis] && nodeR < nodeBox.hi[axis])
|
||||
{
|
||||
float nodeBoxW = nodeBox.hi[axis] - nodeBox.lo[axis];
|
||||
float nodeNewW = nodeR - nodeL;
|
||||
// node box is too big compare to space occupied by primitives?
|
||||
if (1.3f * nodeNewW < nodeBoxW)
|
||||
{
|
||||
stats.updateBVH2();
|
||||
int nextIndex = tempTree.size();
|
||||
// allocate child
|
||||
tempTree.push_back(0);
|
||||
tempTree.push_back(0);
|
||||
tempTree.push_back(0);
|
||||
// write bvh2 clip node
|
||||
stats.updateInner();
|
||||
tempTree[nodeIndex + 0] = (axis << 30) | (1 << 29) | nextIndex;
|
||||
tempTree[nodeIndex + 1] = floatToRawIntBits(nodeL);
|
||||
tempTree[nodeIndex + 2] = floatToRawIntBits(nodeR);
|
||||
// update nodebox and recurse
|
||||
nodeBox.lo[axis] = nodeL;
|
||||
nodeBox.hi[axis] = nodeR;
|
||||
subdivide(left, rightOrig, tempTree, dat, gridBox, nodeBox, nextIndex, depth + 1, stats);
|
||||
return;
|
||||
}
|
||||
}
|
||||
// ensure we are making progress in the subdivision
|
||||
if (right == rightOrig)
|
||||
{
|
||||
// all left
|
||||
if (prevAxis == axis && prevSplit == split) {
|
||||
// we are stuck here - create a leaf
|
||||
stats.updateLeaf(depth, right - left + 1);
|
||||
createNode(tempTree, nodeIndex, left, right);
|
||||
return;
|
||||
}
|
||||
if (clipL <= split) {
|
||||
// keep looping on left half
|
||||
gridBox.hi[axis] = split;
|
||||
prevClip = clipL;
|
||||
wasLeft = true;
|
||||
continue;
|
||||
}
|
||||
gridBox.hi[axis] = split;
|
||||
prevClip = G3D::fnan();
|
||||
}
|
||||
else if (left > right)
|
||||
{
|
||||
// all right
|
||||
if (prevAxis == axis && prevSplit == split) {
|
||||
// we are stuck here - create a leaf
|
||||
stats.updateLeaf(depth, right - left + 1);
|
||||
createNode(tempTree, nodeIndex, left, right);
|
||||
return;
|
||||
}
|
||||
right = rightOrig;
|
||||
if (clipR >= split) {
|
||||
// keep looping on right half
|
||||
gridBox.lo[axis] = split;
|
||||
prevClip = clipR;
|
||||
wasLeft = false;
|
||||
continue;
|
||||
}
|
||||
gridBox.lo[axis] = split;
|
||||
prevClip = G3D::fnan();
|
||||
}
|
||||
else
|
||||
{
|
||||
// we are actually splitting stuff
|
||||
if (prevAxis != -1 && !isnan(prevClip))
|
||||
{
|
||||
// second time through - lets create the previous split
|
||||
// since it produced empty space
|
||||
int nextIndex = tempTree.size();
|
||||
// allocate child node
|
||||
tempTree.push_back(0);
|
||||
tempTree.push_back(0);
|
||||
tempTree.push_back(0);
|
||||
if (wasLeft) {
|
||||
// create a node with a left child
|
||||
// write leaf node
|
||||
stats.updateInner();
|
||||
tempTree[nodeIndex + 0] = (prevAxis << 30) | nextIndex;
|
||||
tempTree[nodeIndex + 1] = floatToRawIntBits(prevClip);
|
||||
tempTree[nodeIndex + 2] = floatToRawIntBits(G3D::inf());
|
||||
} else {
|
||||
// create a node with a right child
|
||||
// write leaf node
|
||||
stats.updateInner();
|
||||
tempTree[nodeIndex + 0] = (prevAxis << 30) | (nextIndex - 3);
|
||||
tempTree[nodeIndex + 1] = floatToRawIntBits(-G3D::inf());
|
||||
tempTree[nodeIndex + 2] = floatToRawIntBits(prevClip);
|
||||
}
|
||||
// count stats for the unused leaf
|
||||
depth++;
|
||||
stats.updateLeaf(depth, 0);
|
||||
// now we keep going as we are, with a new nodeIndex:
|
||||
nodeIndex = nextIndex;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
// compute index of child nodes
|
||||
int nextIndex = tempTree.size();
|
||||
// allocate left node
|
||||
int nl = right - left + 1;
|
||||
int nr = rightOrig - (right + 1) + 1;
|
||||
if (nl > 0) {
|
||||
tempTree.push_back(0);
|
||||
tempTree.push_back(0);
|
||||
tempTree.push_back(0);
|
||||
} else
|
||||
nextIndex -= 3;
|
||||
// allocate right node
|
||||
if (nr > 0) {
|
||||
tempTree.push_back(0);
|
||||
tempTree.push_back(0);
|
||||
tempTree.push_back(0);
|
||||
}
|
||||
// write leaf node
|
||||
stats.updateInner();
|
||||
tempTree[nodeIndex + 0] = (axis << 30) | nextIndex;
|
||||
tempTree[nodeIndex + 1] = floatToRawIntBits(clipL);
|
||||
tempTree[nodeIndex + 2] = floatToRawIntBits(clipR);
|
||||
// prepare L/R child boxes
|
||||
AABound gridBoxL(gridBox), gridBoxR(gridBox);
|
||||
AABound nodeBoxL(nodeBox), nodeBoxR(nodeBox);
|
||||
gridBoxL.hi[axis] = gridBoxR.lo[axis] = split;
|
||||
nodeBoxL.hi[axis] = clipL;
|
||||
nodeBoxR.lo[axis] = clipR;
|
||||
// recurse
|
||||
if (nl > 0)
|
||||
subdivide(left, right, tempTree, dat, gridBoxL, nodeBoxL, nextIndex, depth + 1, stats);
|
||||
else
|
||||
stats.updateLeaf(depth + 1, 0);
|
||||
if (nr > 0)
|
||||
subdivide(right + 1, rightOrig, tempTree, dat, gridBoxR, nodeBoxR, nextIndex + 3, depth + 1, stats);
|
||||
else
|
||||
stats.updateLeaf(depth + 1, 0);
|
||||
}
|
||||
|
||||
bool BIH::writeToFile(FILE *wf) const
|
||||
{
|
||||
uint32 treeSize = tree.size();
|
||||
uint32 check=0, count=0;
|
||||
check += fwrite(&bounds.low(), sizeof(float), 3, wf);
|
||||
check += fwrite(&bounds.high(), sizeof(float), 3, wf);
|
||||
check += fwrite(&treeSize, sizeof(uint32), 1, wf);
|
||||
check += fwrite(&tree[0], sizeof(uint32), treeSize, wf);
|
||||
count = objects.size();
|
||||
check += fwrite(&count, sizeof(uint32), 1, wf);
|
||||
check += fwrite(&objects[0], sizeof(uint32), count, wf);
|
||||
return check == (3 + 3 + 2 + treeSize + count);
|
||||
}
|
||||
|
||||
bool BIH::readFromFile(FILE *rf)
|
||||
{
|
||||
uint32 treeSize;
|
||||
Vector3 lo, hi;
|
||||
uint32 check=0, count=0;
|
||||
check += fread(&lo, sizeof(float), 3, rf);
|
||||
check += fread(&hi, sizeof(float), 3, rf);
|
||||
bounds = AABox(lo, hi);
|
||||
check += fread(&treeSize, sizeof(uint32), 1, rf);
|
||||
tree.resize(treeSize);
|
||||
check += fread(&tree[0], sizeof(uint32), treeSize, rf);
|
||||
check += fread(&count, sizeof(uint32), 1, rf);
|
||||
objects.resize(count); // = new uint32[nObjects];
|
||||
check += fread(&objects[0], sizeof(uint32), count, rf);
|
||||
return check == (3 + 3 + 2 + treeSize + count);
|
||||
}
|
||||
|
||||
void BIH::BuildStats::updateLeaf(int depth, int n)
|
||||
{
|
||||
numLeaves++;
|
||||
minDepth = std::min(depth, minDepth);
|
||||
maxDepth = std::max(depth, maxDepth);
|
||||
sumDepth += depth;
|
||||
minObjects = std::min(n, minObjects);
|
||||
maxObjects = std::max(n, maxObjects);
|
||||
sumObjects += n;
|
||||
int nl = std::min(n, 5);
|
||||
++numLeavesN[nl];
|
||||
}
|
||||
|
||||
void BIH::BuildStats::printStats()
|
||||
{
|
||||
printf("Tree stats:\n");
|
||||
printf(" * Nodes: %d\n", numNodes);
|
||||
printf(" * Leaves: %d\n", numLeaves);
|
||||
printf(" * Objects: min %d\n", minObjects);
|
||||
printf(" avg %.2f\n", (float) sumObjects / numLeaves);
|
||||
printf(" avg(n>0) %.2f\n", (float) sumObjects / (numLeaves - numLeavesN[0]));
|
||||
printf(" max %d\n", maxObjects);
|
||||
printf(" * Depth: min %d\n", minDepth);
|
||||
printf(" avg %.2f\n", (float) sumDepth / numLeaves);
|
||||
printf(" max %d\n", maxDepth);
|
||||
printf(" * Leaves w/: N=0 %3d%%\n", 100 * numLeavesN[0] / numLeaves);
|
||||
printf(" N=1 %3d%%\n", 100 * numLeavesN[1] / numLeaves);
|
||||
printf(" N=2 %3d%%\n", 100 * numLeavesN[2] / numLeaves);
|
||||
printf(" N=3 %3d%%\n", 100 * numLeavesN[3] / numLeaves);
|
||||
printf(" N=4 %3d%%\n", 100 * numLeavesN[4] / numLeaves);
|
||||
printf(" N>4 %3d%%\n", 100 * numLeavesN[5] / numLeaves);
|
||||
printf(" * BVH2 nodes: %d (%3d%%)\n", numBVH2, 100 * numBVH2 / (numNodes + numLeaves - 2 * numBVH2));
|
||||
}
|
||||
@@ -0,0 +1,391 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2010 MaNGOS <http://getmangos.com/>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public 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 _BIH_H
|
||||
#define _BIH_H
|
||||
|
||||
#include <G3D/Vector3.h>
|
||||
#include <G3D/Ray.h>
|
||||
#include <G3D/AABox.h>
|
||||
|
||||
#include <Platform/Define.h>
|
||||
|
||||
#include <stdexcept>
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
#include <limits>
|
||||
#include <cmath>
|
||||
|
||||
#define MAX_STACK_SIZE 64
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#define isnan(x) _isnan(x)
|
||||
#endif
|
||||
|
||||
using G3D::Vector3;
|
||||
using G3D::AABox;
|
||||
using G3D::Ray;
|
||||
|
||||
static inline uint32 floatToRawIntBits(float f)
|
||||
{
|
||||
union
|
||||
{
|
||||
uint32 ival;
|
||||
float fval;
|
||||
} temp;
|
||||
temp.fval=f;
|
||||
return temp.ival;
|
||||
}
|
||||
|
||||
static inline float intBitsToFloat(uint32 i)
|
||||
{
|
||||
union
|
||||
{
|
||||
uint32 ival;
|
||||
float fval;
|
||||
} temp;
|
||||
temp.ival=i;
|
||||
return temp.fval;
|
||||
}
|
||||
|
||||
struct AABound
|
||||
{
|
||||
Vector3 lo, hi;
|
||||
};
|
||||
|
||||
/** Bounding Interval Hierarchy Class.
|
||||
Building and Ray-Intersection functions based on BIH from
|
||||
Sunflow, a Java Raytracer, released under MIT/X11 License
|
||||
http://sunflow.sourceforge.net/
|
||||
Copyright (c) 2003-2007 Christopher Kulla
|
||||
*/
|
||||
|
||||
class BIH
|
||||
{
|
||||
public:
|
||||
BIH() {};
|
||||
template< class T, class BoundsFunc >
|
||||
void build(const std::vector<T> &primitives, BoundsFunc &getBounds, uint32 leafSize = 3, bool printStats=false)
|
||||
{
|
||||
if(primitives.size() == 0)
|
||||
return;
|
||||
buildData dat;
|
||||
dat.maxPrims = leafSize;
|
||||
dat.numPrims = primitives.size();
|
||||
dat.indices = new uint32[dat.numPrims];
|
||||
dat.primBound = new AABox[dat.numPrims];
|
||||
getBounds(primitives[0], bounds);
|
||||
for (uint32 i=0; i<dat.numPrims; ++i)
|
||||
{
|
||||
dat.indices[i] = i;
|
||||
AABox tb;
|
||||
getBounds(primitives[i], dat.primBound[i]);
|
||||
bounds.merge(dat.primBound[i]);
|
||||
}
|
||||
std::vector<uint32> tempTree;
|
||||
BuildStats stats;
|
||||
buildHierarchy(tempTree, dat, stats);
|
||||
if (printStats)
|
||||
stats.printStats();
|
||||
|
||||
objects.resize(dat.numPrims);
|
||||
for (uint32 i=0; i<dat.numPrims; ++i)
|
||||
objects[i] = dat.indices[i];
|
||||
//nObjects = dat.numPrims;
|
||||
tree = tempTree;
|
||||
delete[] dat.primBound;
|
||||
delete[] dat.indices;
|
||||
}
|
||||
uint32 primCount() { return objects.size(); }
|
||||
|
||||
template<typename RayCallback>
|
||||
void intersectRay(const Ray &r, RayCallback& intersectCallback, float &maxDist, bool stopAtFirst=false) const
|
||||
{
|
||||
float intervalMin = 0.f;
|
||||
float intervalMax = maxDist;
|
||||
Vector3 org = r.origin();
|
||||
Vector3 dir = r.direction();
|
||||
Vector3 invDir;
|
||||
float t1, t2;
|
||||
for(int i=0; i<3; ++i)
|
||||
{
|
||||
invDir[i] = 1.f / dir[i];
|
||||
t1 = (bounds.low()[i] - org[i]) * invDir[i];
|
||||
t2 = (bounds.high()[i] - org[i]) * invDir[i];
|
||||
if (invDir[i] > 0) {
|
||||
if (t1 > intervalMin)
|
||||
intervalMin = t1;
|
||||
if (t2 < intervalMax)
|
||||
intervalMax = t2;
|
||||
} else {
|
||||
if (t2 > intervalMin)
|
||||
intervalMin = t2;
|
||||
if (t1 < intervalMax)
|
||||
intervalMax = t1;
|
||||
}
|
||||
if (intervalMin > intervalMax)
|
||||
return;
|
||||
}
|
||||
|
||||
uint32 offsetFront[3];
|
||||
uint32 offsetBack[3];
|
||||
uint32 offsetFront3[3];
|
||||
uint32 offsetBack3[3];
|
||||
// compute custom offsets from direction sign bit
|
||||
|
||||
for(int i=0; i<3; ++i)
|
||||
{
|
||||
offsetFront[i] = floatToRawIntBits(dir[i]) >> 31;
|
||||
offsetBack[i] = offsetFront[i] ^ 1;
|
||||
offsetFront3[i] = offsetFront[i] * 3;
|
||||
offsetBack3[i] = offsetBack[i] * 3;
|
||||
|
||||
// avoid always adding 1 during the inner loop
|
||||
++offsetFront[i];
|
||||
++offsetBack[i];
|
||||
}
|
||||
|
||||
StackNode stack[MAX_STACK_SIZE];
|
||||
int stackPos = 0;
|
||||
int node = 0;
|
||||
|
||||
while (true) {
|
||||
while (true)
|
||||
{
|
||||
uint32 tn = tree[node];
|
||||
uint32 axis = (tn & (3 << 30)) >> 30;
|
||||
bool BVH2 = tn & (1 << 29);
|
||||
int offset = tn & ~(7 << 29);
|
||||
if (!BVH2)
|
||||
{
|
||||
if (axis < 3)
|
||||
{
|
||||
// "normal" interior node
|
||||
float tf = (intBitsToFloat(tree[node + offsetFront[axis]]) - org[axis]) * invDir[axis];
|
||||
float tb = (intBitsToFloat(tree[node + offsetBack[axis]]) - org[axis]) * invDir[axis];
|
||||
// ray passes between clip zones
|
||||
if (tf < intervalMin && tb > intervalMax)
|
||||
break;
|
||||
int back = offset + offsetBack3[axis];
|
||||
node = back;
|
||||
// ray passes through far node only
|
||||
if (tf < intervalMin) {
|
||||
intervalMin = (tb >= intervalMin) ? tb : intervalMin;
|
||||
continue;
|
||||
}
|
||||
node = offset + offsetFront3[axis]; // front
|
||||
// ray passes through near node only
|
||||
if (tb > intervalMax) {
|
||||
intervalMax = (tf <= intervalMax) ? tf : intervalMax;
|
||||
continue;
|
||||
}
|
||||
// ray passes through both nodes
|
||||
// push back node
|
||||
stack[stackPos].node = back;
|
||||
stack[stackPos].tnear = (tb >= intervalMin) ? tb : intervalMin;
|
||||
stack[stackPos].tfar = intervalMax;
|
||||
stackPos++;
|
||||
// update ray interval for front node
|
||||
intervalMax = (tf <= intervalMax) ? tf : intervalMax;
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
// leaf - test some objects
|
||||
int n = tree[node + 1];
|
||||
while (n > 0) {
|
||||
bool hit = intersectCallback(r, objects[offset], maxDist, stopAtFirst);
|
||||
if(stopAtFirst && hit) return;
|
||||
--n;
|
||||
++offset;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (axis>2)
|
||||
return; // should not happen
|
||||
float tf = (intBitsToFloat(tree[node + offsetFront[axis]]) - org[axis]) * invDir[axis];
|
||||
float tb = (intBitsToFloat(tree[node + offsetBack[axis]]) - org[axis]) * invDir[axis];
|
||||
node = offset;
|
||||
intervalMin = (tf >= intervalMin) ? tf : intervalMin;
|
||||
intervalMax = (tb <= intervalMax) ? tb : intervalMax;
|
||||
if (intervalMin > intervalMax)
|
||||
break;
|
||||
continue;
|
||||
}
|
||||
} // traversal loop
|
||||
do
|
||||
{
|
||||
// stack is empty?
|
||||
if (stackPos == 0)
|
||||
return;
|
||||
// move back up the stack
|
||||
stackPos--;
|
||||
intervalMin = stack[stackPos].tnear;
|
||||
if (maxDist < intervalMin)
|
||||
continue;
|
||||
node = stack[stackPos].node;
|
||||
intervalMax = stack[stackPos].tfar;
|
||||
break;
|
||||
} while (true);
|
||||
}
|
||||
}
|
||||
|
||||
template<typename IsectCallback>
|
||||
void intersectPoint(const Vector3 &p, IsectCallback& intersectCallback) const
|
||||
{
|
||||
if (!bounds.contains(p))
|
||||
return;
|
||||
|
||||
StackNode stack[MAX_STACK_SIZE];
|
||||
int stackPos = 0;
|
||||
int node = 0;
|
||||
|
||||
while (true) {
|
||||
while (true)
|
||||
{
|
||||
uint32 tn = tree[node];
|
||||
uint32 axis = (tn & (3 << 30)) >> 30;
|
||||
bool BVH2 = tn & (1 << 29);
|
||||
int offset = tn & ~(7 << 29);
|
||||
if (!BVH2)
|
||||
{
|
||||
if (axis < 3)
|
||||
{
|
||||
// "normal" interior node
|
||||
float tl = intBitsToFloat(tree[node + 1]);
|
||||
float tr = intBitsToFloat(tree[node + 2]);
|
||||
// point is between clip zones
|
||||
if (tl < p[axis] && tr > p[axis])
|
||||
break;
|
||||
int right = offset + 3;
|
||||
node = right;
|
||||
// point is in right node only
|
||||
if (tl < p[axis]) {
|
||||
continue;
|
||||
}
|
||||
node = offset; // left
|
||||
// point is in left node only
|
||||
if (tr > p[axis]) {
|
||||
continue;
|
||||
}
|
||||
// point is in both nodes
|
||||
// push back right node
|
||||
stack[stackPos].node = right;
|
||||
stackPos++;
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
// leaf - test some objects
|
||||
int n = tree[node + 1];
|
||||
while (n > 0) {
|
||||
intersectCallback(p, objects[offset]); // !!!
|
||||
--n;
|
||||
++offset;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
else // BVH2 node (empty space cut off left and right)
|
||||
{
|
||||
if (axis>2)
|
||||
return; // should not happen
|
||||
float tl = intBitsToFloat(tree[node + 1]);
|
||||
float tr = intBitsToFloat(tree[node + 2]);
|
||||
node = offset;
|
||||
if (tl > p[axis] || tr < p[axis])
|
||||
break;
|
||||
continue;
|
||||
}
|
||||
} // traversal loop
|
||||
|
||||
// stack is empty?
|
||||
if (stackPos == 0)
|
||||
return;
|
||||
// move back up the stack
|
||||
stackPos--;
|
||||
node = stack[stackPos].node;
|
||||
}
|
||||
}
|
||||
|
||||
bool writeToFile(FILE *wf) const;
|
||||
bool readFromFile(FILE *rf);
|
||||
|
||||
protected:
|
||||
std::vector<uint32> tree;
|
||||
std::vector<uint32> objects;
|
||||
AABox bounds;
|
||||
|
||||
struct buildData
|
||||
{
|
||||
uint32 *indices;
|
||||
AABox *primBound;
|
||||
uint32 numPrims;
|
||||
int maxPrims;
|
||||
};
|
||||
struct StackNode
|
||||
{
|
||||
uint32 node;
|
||||
float tnear;
|
||||
float tfar;
|
||||
};
|
||||
|
||||
class BuildStats
|
||||
{
|
||||
private:
|
||||
int numNodes;
|
||||
int numLeaves;
|
||||
int sumObjects;
|
||||
int minObjects;
|
||||
int maxObjects;
|
||||
int sumDepth;
|
||||
int minDepth;
|
||||
int maxDepth;
|
||||
int numLeavesN[6];
|
||||
int numBVH2;
|
||||
|
||||
public:
|
||||
BuildStats():
|
||||
numNodes(0), numLeaves(0), sumObjects(0), minObjects(0x0FFFFFFF),
|
||||
maxObjects(0xFFFFFFFF), sumDepth(0), minDepth(0x0FFFFFFF),
|
||||
maxDepth(0xFFFFFFFF), numBVH2(0)
|
||||
{
|
||||
for(int i=0; i<6; ++i) numLeavesN[i] = 0;
|
||||
}
|
||||
|
||||
void updateInner() { numNodes++; }
|
||||
void updateBVH2() { numBVH2++; }
|
||||
void updateLeaf(int depth, int n);
|
||||
void printStats();
|
||||
};
|
||||
|
||||
void buildHierarchy(std::vector<uint32> &tempTree, buildData &dat, BuildStats &stats);
|
||||
|
||||
void createNode(std::vector<uint32> &tempTree, int nodeIndex, uint32 left, uint32 right) {
|
||||
// write leaf node
|
||||
tempTree[nodeIndex + 0] = (3 << 30) | left;
|
||||
tempTree[nodeIndex + 1] = right - left + 1;
|
||||
}
|
||||
|
||||
void subdivide(int left, int right, std::vector<uint32> &tempTree, buildData &dat, AABound &gridBox, AABound &nodeBox, int nodeIndex, int depth, BuildStats &stats);
|
||||
};
|
||||
|
||||
#endif // _BIH_H
|
||||
@@ -0,0 +1,30 @@
|
||||
|
||||
########### next target ###############
|
||||
|
||||
SET(vmaps_STAT_SRCS
|
||||
BIH.h
|
||||
BIH.cpp
|
||||
IVMapManager.h
|
||||
MapTree.cpp
|
||||
MapTree.h
|
||||
ModelInstance.cpp
|
||||
ModelInstance.h
|
||||
TileAssembler.cpp
|
||||
TileAssembler.h
|
||||
VMapDefinitions.h
|
||||
VMapFactory.cpp
|
||||
VMapFactory.h
|
||||
VMapManager2.cpp
|
||||
VMapManager2.h
|
||||
VMapTools.h
|
||||
WorldModel.cpp
|
||||
WorldModel.h
|
||||
)
|
||||
|
||||
include_directories(
|
||||
${ACE_INCLUDE_DIR}
|
||||
${CMAKE_SOURCE_DIR}/src/framework
|
||||
${CMAKE_SOURCE_DIR}/dep/include/g3dlite
|
||||
)
|
||||
|
||||
add_library(vmaps STATIC ${vmaps_STAT_SRCS})
|
||||
@@ -0,0 +1,106 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2010 MaNGOS <http://getmangos.com/>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public 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 _IVMAPMANAGER_H
|
||||
#define _IVMAPMANAGER_H
|
||||
|
||||
#include<string>
|
||||
#include <Platform/Define.h>
|
||||
|
||||
//===========================================================
|
||||
|
||||
/**
|
||||
This is the minimum interface to the VMapMamager.
|
||||
*/
|
||||
|
||||
namespace VMAP
|
||||
{
|
||||
|
||||
enum VMAP_LOAD_RESULT
|
||||
{
|
||||
VMAP_LOAD_RESULT_ERROR,
|
||||
VMAP_LOAD_RESULT_OK,
|
||||
VMAP_LOAD_RESULT_IGNORED,
|
||||
};
|
||||
|
||||
#define VMAP_INVALID_HEIGHT -100000.0f // for check
|
||||
#define VMAP_INVALID_HEIGHT_VALUE -200000.0f // real assigned value in unknown height case
|
||||
|
||||
//===========================================================
|
||||
class IVMapManager
|
||||
{
|
||||
private:
|
||||
bool iEnableLineOfSightCalc;
|
||||
bool iEnableHeightCalc;
|
||||
|
||||
public:
|
||||
IVMapManager() : iEnableLineOfSightCalc(true), iEnableHeightCalc(true) {}
|
||||
|
||||
virtual ~IVMapManager(void) {}
|
||||
|
||||
virtual int loadMap(const char* pBasePath, unsigned int pMapId, int x, int y) = 0;
|
||||
|
||||
virtual bool existsMap(const char* pBasePath, unsigned int pMapId, int x, int y) = 0;
|
||||
|
||||
virtual void unloadMap(unsigned int pMapId, int x, int y) = 0;
|
||||
virtual void unloadMap(unsigned int pMapId) = 0;
|
||||
|
||||
virtual bool isInLineOfSight(unsigned int pMapId, float x1, float y1, float z1, float x2, float y2, float z2) = 0;
|
||||
virtual float getHeight(unsigned int pMapId, float x, float y, float z) = 0;
|
||||
/**
|
||||
test if we hit an object. return true if we hit one. rx,ry,rz will hold the hit position or the dest position, if no intersection was found
|
||||
return a position, that is pReduceDist closer to the origin
|
||||
*/
|
||||
virtual bool getObjectHitPos(unsigned int pMapId, float x1, float y1, float z1, float x2, float y2, float z2, float& rx, float &ry, float& rz, float pModifyDist) = 0;
|
||||
/**
|
||||
send debug commands
|
||||
*/
|
||||
virtual bool processCommand(char *pCommand)= 0;
|
||||
|
||||
/**
|
||||
Enable/disable LOS calculation
|
||||
It is enabled by default. If it is enabled in mid game the maps have to loaded manualy
|
||||
*/
|
||||
void setEnableLineOfSightCalc(bool pVal) { iEnableLineOfSightCalc = pVal; }
|
||||
/**
|
||||
Enable/disable model height calculation
|
||||
It is enabled by default. If it is enabled in mid game the maps have to loaded manualy
|
||||
*/
|
||||
void setEnableHeightCalc(bool pVal) { iEnableHeightCalc = pVal; }
|
||||
|
||||
bool isLineOfSightCalcEnabled() const { return(iEnableLineOfSightCalc); }
|
||||
bool isHeightCalcEnabled() const { return(iEnableHeightCalc); }
|
||||
bool isMapLoadingEnabled() const { return(iEnableLineOfSightCalc || iEnableHeightCalc ); }
|
||||
|
||||
virtual std::string getDirFileName(unsigned int pMapId, int x, int y) const =0;
|
||||
/**
|
||||
Block maps from being used.
|
||||
parameter: String of map ids. Delimiter = ","
|
||||
e.g.: "0,1,530"
|
||||
*/
|
||||
virtual void preventMapsFromBeingUsed(const char* pMapIdString) =0;
|
||||
/**
|
||||
Query world model area info.
|
||||
\param z gets adjusted to the ground height for which this are info is valid
|
||||
*/
|
||||
virtual bool getAreaInfo(unsigned int pMapId, float x, float y, float &z, uint32 &flags, int32 &adtId, int32 &rootId, int32 &groupId) const=0;
|
||||
virtual bool GetLiquidLevel(uint32 pMapId, float x, float y, float z, uint8 ReqLiquidType, float &level, float &floor, uint32 &type) const=0;
|
||||
};
|
||||
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,450 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2010 MaNGOS <http://getmangos.com/>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public 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 "MapTree.h"
|
||||
#include "ModelInstance.h"
|
||||
#include "VMapManager2.h"
|
||||
#include "VMapDefinitions.h"
|
||||
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
#include <iomanip>
|
||||
|
||||
using G3D::Vector3;
|
||||
|
||||
namespace VMAP
|
||||
{
|
||||
|
||||
class MapRayCallback
|
||||
{
|
||||
public:
|
||||
MapRayCallback(ModelInstance *val): prims(val) {}
|
||||
ModelInstance *prims;
|
||||
bool operator()(const G3D::Ray& ray, uint32 entry, float& distance, bool pStopAtFirstHit=true)
|
||||
{
|
||||
return prims[entry].intersectRay(ray, distance, pStopAtFirstHit);
|
||||
//std::cout << "trying to intersect '" << entity->name << "'\n";
|
||||
}
|
||||
};
|
||||
|
||||
class AreaInfoCallback
|
||||
{
|
||||
public:
|
||||
AreaInfoCallback(ModelInstance *val): prims(val) {}
|
||||
void operator()(const Vector3& point, uint32 entry)
|
||||
{
|
||||
#ifdef VMAP_DEBUG
|
||||
std::cout << "trying to intersect '" << prims[entry].name << "'\n";
|
||||
#endif
|
||||
prims[entry].intersectPoint(point, aInfo);
|
||||
}
|
||||
|
||||
ModelInstance *prims;
|
||||
AreaInfo aInfo;
|
||||
};
|
||||
|
||||
class LocationInfoCallback
|
||||
{
|
||||
public:
|
||||
LocationInfoCallback(ModelInstance *val, LocationInfo &info): prims(val), locInfo(info), result(false) {}
|
||||
void operator()(const Vector3& point, uint32 entry)
|
||||
{
|
||||
#ifdef VMAP_DEBUG
|
||||
std::cout << "trying to intersect '" << prims[entry].name << "'\n";
|
||||
#endif
|
||||
if (prims[entry].GetLocationInfo(point, locInfo))
|
||||
result = true;
|
||||
}
|
||||
|
||||
ModelInstance *prims;
|
||||
LocationInfo &locInfo;
|
||||
bool result;
|
||||
};
|
||||
|
||||
|
||||
//=========================================================
|
||||
|
||||
std::string StaticMapTree::getTileFileName(uint32 mapID, uint32 tileX, uint32 tileY)
|
||||
{
|
||||
std::stringstream tilefilename;
|
||||
tilefilename.fill('0');
|
||||
tilefilename << std::setw(3) << mapID << "_";
|
||||
//tilefilename << std::setw(2) << tileX << "_" << std::setw(2) << tileY << ".vmtile";
|
||||
tilefilename << std::setw(2) << tileY << "_" << std::setw(2) << tileX << ".vmtile";
|
||||
return tilefilename.str();
|
||||
}
|
||||
|
||||
bool StaticMapTree::getAreaInfo(Vector3 &pos, uint32 &flags, int32 &adtId, int32 &rootId, int32 &groupId) const
|
||||
{
|
||||
AreaInfoCallback intersectionCallBack(iTreeValues);
|
||||
iTree.intersectPoint(pos, intersectionCallBack);
|
||||
if (intersectionCallBack.aInfo.result)
|
||||
{
|
||||
flags = intersectionCallBack.aInfo.flags;
|
||||
adtId = intersectionCallBack.aInfo.adtId;
|
||||
rootId = intersectionCallBack.aInfo.rootId;
|
||||
groupId = intersectionCallBack.aInfo.groupId;
|
||||
pos.z = intersectionCallBack.aInfo.ground_Z;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool StaticMapTree::GetLocationInfo(const Vector3 &pos, LocationInfo &info) const
|
||||
{
|
||||
LocationInfoCallback intersectionCallBack(iTreeValues, info);
|
||||
iTree.intersectPoint(pos, intersectionCallBack);
|
||||
return intersectionCallBack.result;
|
||||
}
|
||||
|
||||
StaticMapTree::StaticMapTree(uint32 mapID, const std::string &basePath):
|
||||
iMapID(mapID), /* iTree(0), */ iTreeValues(0), iBasePath(basePath)
|
||||
{
|
||||
if (iBasePath.length() > 0 && (iBasePath[iBasePath.length()-1] != '/' || iBasePath[iBasePath.length()-1] != '\\'))
|
||||
{
|
||||
iBasePath.append("/");
|
||||
}
|
||||
}
|
||||
|
||||
//=========================================================
|
||||
//! Make sure to call unloadMap() to unregister acquired model references before destroying
|
||||
StaticMapTree::~StaticMapTree()
|
||||
{
|
||||
delete[] iTreeValues;
|
||||
}
|
||||
|
||||
//=========================================================
|
||||
/**
|
||||
return dist to hit or inf() if no hit
|
||||
*/
|
||||
|
||||
float StaticMapTree::getIntersectionTime(const G3D::Ray& pRay, float pMaxDist, bool pStopAtFirstHit) const
|
||||
{
|
||||
float distance = pMaxDist;
|
||||
MapRayCallback intersectionCallBack(iTreeValues);
|
||||
iTree.intersectRay(pRay, intersectionCallBack, distance, pStopAtFirstHit);
|
||||
return distance;
|
||||
}
|
||||
//=========================================================
|
||||
|
||||
bool StaticMapTree::isInLineOfSight(const Vector3& pos1, const Vector3& pos2) const
|
||||
{
|
||||
bool result = true;
|
||||
float maxDist = (pos2 - pos1).magnitude();
|
||||
// prevent NaN values which can cause BIH intersection to enter infinite loop
|
||||
if (maxDist < 1e-10f)
|
||||
return true;
|
||||
// direction with length of 1
|
||||
G3D::Ray ray = G3D::Ray::fromOriginAndDirection(pos1, (pos2 - pos1)/maxDist);
|
||||
float resultDist = getIntersectionTime(ray, maxDist, true);
|
||||
if (resultDist < maxDist)
|
||||
{
|
||||
result = false;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
//=========================================================
|
||||
/**
|
||||
When moving from pos1 to pos2 check if we hit an object. Return true and the position if we hit one
|
||||
Return the hit pos or the original dest pos
|
||||
*/
|
||||
|
||||
bool StaticMapTree::getObjectHitPos(const Vector3& pPos1, const Vector3& pPos2, Vector3& pResultHitPos, float pModifyDist) const
|
||||
{
|
||||
bool result=false;
|
||||
float maxDist = (pPos2 - pPos1).magnitude();
|
||||
// prevent NaN values which can cause BIH intersection to enter infinite loop
|
||||
if (maxDist < 1e-10f)
|
||||
{
|
||||
pResultHitPos = pPos2;
|
||||
return false;
|
||||
}
|
||||
Vector3 dir = (pPos2 - pPos1)/maxDist; // direction with length of 1
|
||||
G3D::Ray ray(pPos1, dir);
|
||||
float dist = getIntersectionTime(ray, maxDist, false);
|
||||
if (dist < maxDist)
|
||||
{
|
||||
pResultHitPos = pPos1 + dir * dist;
|
||||
if (pModifyDist < 0)
|
||||
{
|
||||
if ((pResultHitPos - pPos1).magnitude() > -pModifyDist)
|
||||
{
|
||||
pResultHitPos = pResultHitPos + dir*pModifyDist;
|
||||
}
|
||||
else
|
||||
{
|
||||
pResultHitPos = pPos1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
pResultHitPos = pResultHitPos + dir*pModifyDist;
|
||||
}
|
||||
result = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
pResultHitPos = pPos2;
|
||||
result = false;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
//=========================================================
|
||||
|
||||
float StaticMapTree::getHeight(const Vector3& pPos) const
|
||||
{
|
||||
float height = G3D::inf();
|
||||
Vector3 dir = Vector3(0,0,-1);
|
||||
G3D::Ray ray(pPos, dir); // direction with length of 1
|
||||
float maxDist = VMapDefinitions::getMaxCanFallDistance();
|
||||
float dist = getIntersectionTime(ray, maxDist, false);
|
||||
if (dist < maxDist)
|
||||
{
|
||||
height = pPos.z - dist;
|
||||
}
|
||||
return(height);
|
||||
}
|
||||
|
||||
//=========================================================
|
||||
|
||||
bool StaticMapTree::CanLoadMap(const std::string &vmapPath, uint32 mapID, uint32 tileX, uint32 tileY)
|
||||
{
|
||||
std::string basePath = vmapPath;
|
||||
if (basePath.length() > 0 && (basePath[basePath.length()-1] != '/' || basePath[basePath.length()-1] != '\\'))
|
||||
basePath.append("/");
|
||||
std::string fullname = basePath + VMapManager2::getMapFileName(mapID);
|
||||
bool success = true;
|
||||
FILE *rf = fopen(fullname.c_str(), "rb");
|
||||
if (!rf)
|
||||
return false;
|
||||
// TODO: check magic number when implemented...
|
||||
char tiled;
|
||||
char chunk[8];
|
||||
if (!readChunk(rf, chunk, VMAP_MAGIC, 8) || fread(&tiled, sizeof(char), 1, rf) != 1)
|
||||
{
|
||||
fclose(rf);
|
||||
return false;
|
||||
}
|
||||
if (tiled)
|
||||
{
|
||||
std::string tilefile = basePath + getTileFileName(mapID, tileX, tileY);
|
||||
FILE* tf = fopen(tilefile.c_str(), "rb");
|
||||
if (!tf)
|
||||
success = false;
|
||||
else
|
||||
fclose(tf);
|
||||
}
|
||||
fclose(rf);
|
||||
return success;
|
||||
}
|
||||
|
||||
//=========================================================
|
||||
|
||||
bool StaticMapTree::InitMap(const std::string &fname, VMapManager2 *vm)
|
||||
{
|
||||
std::cout << "Initializing StaticMapTree '" << fname << "'\n";
|
||||
bool success = true;
|
||||
std::string fullname = iBasePath + fname;
|
||||
FILE *rf = fopen(fullname.c_str(), "rb");
|
||||
if (!rf)
|
||||
return false;
|
||||
else
|
||||
{
|
||||
char chunk[8];
|
||||
//general info
|
||||
if (!readChunk(rf, chunk, VMAP_MAGIC, 8)) success = false;
|
||||
char tiled;
|
||||
if (success && fread(&tiled, sizeof(char), 1, rf) != 1) success = false;
|
||||
iIsTiled = bool(tiled);
|
||||
// Nodes
|
||||
if (success && !readChunk(rf, chunk, "NODE", 4)) success = false;
|
||||
if (success) success = iTree.readFromFile(rf);
|
||||
if (success)
|
||||
{
|
||||
iNTreeValues = iTree.primCount();
|
||||
iTreeValues = new ModelInstance[iNTreeValues];
|
||||
}
|
||||
|
||||
if (success && !readChunk(rf, chunk, "GOBJ", 4)) success = false;
|
||||
// global model spawns
|
||||
// only non-tiled maps have them, and if so exactly one (so far at least...)
|
||||
ModelSpawn spawn;
|
||||
#ifdef VMAP_DEBUG
|
||||
std::cout << "Map isTiled:" << bool(iIsTiled) << std::endl;
|
||||
#endif
|
||||
if (!iIsTiled && ModelSpawn::readFromFile(rf, spawn))
|
||||
{
|
||||
WorldModel *model = vm->acquireModelInstance(iBasePath, spawn.name);
|
||||
std::cout << "StaticMapTree::InitMap(): loading " << spawn.name << std::endl;
|
||||
if (model)
|
||||
{
|
||||
// assume that global model always is the first and only tree value (could be improved...)
|
||||
iTreeValues[0] = ModelInstance(spawn, model);
|
||||
iLoadedSpawns[0] = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
success = false;
|
||||
std::cout << "error: could not acquire WorldModel pointer!\n";
|
||||
}
|
||||
}
|
||||
|
||||
fclose(rf);
|
||||
}
|
||||
return success;
|
||||
}
|
||||
|
||||
//=========================================================
|
||||
|
||||
void StaticMapTree::UnloadMap(VMapManager2 *vm)
|
||||
{
|
||||
for (loadedSpawnMap::iterator i = iLoadedSpawns.begin(); i != iLoadedSpawns.end(); ++i)
|
||||
{
|
||||
iTreeValues[i->first].setUnloaded();
|
||||
for (uint32 refCount = 0; refCount < i->second; ++refCount)
|
||||
vm->releaseModelInstance(iTreeValues[i->first].name);
|
||||
}
|
||||
iLoadedSpawns.clear();
|
||||
iLoadedTiles.clear();
|
||||
}
|
||||
|
||||
//=========================================================
|
||||
|
||||
bool StaticMapTree::LoadMapTile(uint32 tileX, uint32 tileY, VMapManager2 *vm)
|
||||
{
|
||||
if (!iIsTiled)
|
||||
{
|
||||
// currently, core creates grids for all maps, whether it has terrain tiles or not
|
||||
// so we need "fake" tile loads to know when we can unload map geometry
|
||||
iLoadedTiles[packTileID(tileX, tileY)] = false;
|
||||
return true;
|
||||
}
|
||||
if (!iTreeValues)
|
||||
{
|
||||
std::cout << "Tree has not been initialized!\n";
|
||||
return false;
|
||||
}
|
||||
bool result = true;
|
||||
|
||||
std::string tilefile = iBasePath + getTileFileName(iMapID, tileX, tileY);
|
||||
FILE* tf = fopen(tilefile.c_str(), "rb");
|
||||
if (tf)
|
||||
{
|
||||
uint32 numSpawns;
|
||||
if (fread(&numSpawns, sizeof(uint32), 1, tf) != 1)
|
||||
result = false;
|
||||
for (uint32 i=0; i<numSpawns && result; ++i)
|
||||
{
|
||||
// read model spawns
|
||||
ModelSpawn spawn;
|
||||
result = ModelSpawn::readFromFile(tf, spawn);
|
||||
if (result)
|
||||
{
|
||||
// acquire model instance
|
||||
WorldModel *model = vm->acquireModelInstance(iBasePath, spawn.name);
|
||||
if (!model) std::cout << "error: could not acquire WorldModel pointer!\n";
|
||||
|
||||
// update tree
|
||||
uint32 referencedVal;
|
||||
|
||||
fread(&referencedVal, sizeof(uint32), 1, tf);
|
||||
if (!iLoadedSpawns.count(referencedVal))
|
||||
{
|
||||
#ifdef VMAP_DEBUG
|
||||
if (referencedVal > iNTreeValues)
|
||||
{
|
||||
std::cout << "invalid tree element! (" << referencedVal << "/" << iNTreeValues << ")\n";
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
iTreeValues[referencedVal] = ModelInstance(spawn, model);
|
||||
iLoadedSpawns[referencedVal] = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
++iLoadedSpawns[referencedVal];
|
||||
#ifdef VMAP_DEBUG
|
||||
if (iTreeValues[referencedVal].ID != spawn.ID) std::cout << "error: trying to load wrong spawn in node!\n";
|
||||
else if (iTreeValues[referencedVal].name != spawn.name) std::cout << "error: name collision on GUID="<< spawn.ID << "\n";
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
iLoadedTiles[packTileID(tileX, tileY)] = true;
|
||||
fclose(tf);
|
||||
}
|
||||
else
|
||||
iLoadedTiles[packTileID(tileX, tileY)] = false;
|
||||
return result;
|
||||
}
|
||||
|
||||
//=========================================================
|
||||
|
||||
void StaticMapTree::UnloadMapTile(uint32 tileX, uint32 tileY, VMapManager2 *vm)
|
||||
{
|
||||
uint32 tileID = packTileID(tileX, tileY);
|
||||
loadedTileMap::iterator tile = iLoadedTiles.find(tileID);
|
||||
if (tile == iLoadedTiles.end())
|
||||
{
|
||||
std::cout << "WARNING: trying to unload non-loaded tile. Map:" << iMapID << " X:" << tileX << " Y:" << tileY << std::endl;
|
||||
return;
|
||||
}
|
||||
if (tile->second) // file associated with tile
|
||||
{
|
||||
std::string tilefile = iBasePath + getTileFileName(iMapID, tileX, tileY);
|
||||
FILE* tf = fopen(tilefile.c_str(), "rb");
|
||||
if (tf)
|
||||
{
|
||||
bool result=true;
|
||||
uint32 numSpawns;
|
||||
if (fread(&numSpawns, sizeof(uint32), 1, tf) != 1)
|
||||
result = false;
|
||||
for (uint32 i=0; i<numSpawns && result; ++i)
|
||||
{
|
||||
// read model spawns
|
||||
ModelSpawn spawn;
|
||||
result = ModelSpawn::readFromFile(tf, spawn);
|
||||
if (result)
|
||||
{
|
||||
// release model instance
|
||||
vm->releaseModelInstance(spawn.name);
|
||||
|
||||
// update tree
|
||||
uint32 referencedNode;
|
||||
|
||||
fread(&referencedNode, sizeof(uint32), 1, tf);
|
||||
if (!iLoadedSpawns.count(referencedNode))
|
||||
{
|
||||
std::cout << "error! trying to unload non-referenced model '" << spawn.name << "' (ID:" << spawn.ID << ")\n";
|
||||
}
|
||||
else if (--iLoadedSpawns[referencedNode] == 0)
|
||||
{
|
||||
//std::cout << "MapTree: removing '" << spawn.name << "' from tree\n";
|
||||
iTreeValues[referencedNode].setUnloaded();
|
||||
iLoadedSpawns.erase(referencedNode);
|
||||
}
|
||||
}
|
||||
}
|
||||
fclose(tf);
|
||||
}
|
||||
}
|
||||
iLoadedTiles.erase(tile);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,97 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2010 MaNGOS <http://getmangos.com/>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public 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 _MAPTREE_H
|
||||
#define _MAPTREE_H
|
||||
|
||||
#include "Platform/Define.h"
|
||||
#include "Utilities/UnorderedMap.h"
|
||||
#include "BIH.h"
|
||||
|
||||
namespace VMAP
|
||||
{
|
||||
class ModelInstance;
|
||||
class GroupModel;
|
||||
class VMapManager2;
|
||||
|
||||
struct LocationInfo
|
||||
{
|
||||
LocationInfo(): hitInstance(0), hitModel(0), ground_Z(-G3D::inf()) {};
|
||||
const ModelInstance *hitInstance;
|
||||
const GroupModel *hitModel;
|
||||
float ground_Z;
|
||||
};
|
||||
|
||||
class StaticMapTree
|
||||
{
|
||||
typedef UNORDERED_MAP<uint32, bool> loadedTileMap;
|
||||
typedef UNORDERED_MAP<uint32, uint32> loadedSpawnMap;
|
||||
private:
|
||||
uint32 iMapID;
|
||||
bool iIsTiled;
|
||||
BIH iTree;
|
||||
ModelInstance *iTreeValues; // the tree entries
|
||||
uint32 iNTreeValues;
|
||||
|
||||
// Store all the map tile idents that are loaded for that map
|
||||
// some maps are not splitted into tiles and we have to make sure, not removing the map before all tiles are removed
|
||||
// empty tiles have no tile file, hence map with bool instead of just a set (consistency check)
|
||||
loadedTileMap iLoadedTiles;
|
||||
// stores <tree_index, reference_count> to invalidate tree values, unload map, and to be able to report errors
|
||||
loadedSpawnMap iLoadedSpawns;
|
||||
std::string iBasePath;
|
||||
|
||||
private:
|
||||
float getIntersectionTime(const G3D::Ray& pRay, float pMaxDist, bool pStopAtFirstHit) const;
|
||||
//bool containsLoadedMapTile(unsigned int pTileIdent) const { return(iLoadedMapTiles.containsKey(pTileIdent)); }
|
||||
public:
|
||||
static std::string getTileFileName(uint32 mapID, uint32 tileX, uint32 tileY);
|
||||
static uint32 packTileID(uint32 tileX, uint32 tileY) { return tileX<<16 | tileY; }
|
||||
static void unpackTileID(uint32 ID, uint32 &tileX, uint32 &tileY) { tileX = ID>>16; tileY = ID&0xFF; }
|
||||
static bool CanLoadMap(const std::string &basePath, uint32 mapID, uint32 tileX, uint32 tileY);
|
||||
|
||||
StaticMapTree(uint32 mapID, const std::string &basePath);
|
||||
~StaticMapTree();
|
||||
|
||||
bool isInLineOfSight(const G3D::Vector3& pos1, const G3D::Vector3& pos2) const;
|
||||
bool getObjectHitPos(const G3D::Vector3& pos1, const G3D::Vector3& pos2, G3D::Vector3& pResultHitPos, float pModifyDist) const;
|
||||
float getHeight(const G3D::Vector3& pPos) const;
|
||||
bool getAreaInfo(G3D::Vector3 &pos, uint32 &flags, int32 &adtId, int32 &rootId, int32 &groupId) const;
|
||||
bool GetLocationInfo(const Vector3 &pos, LocationInfo &info) const;
|
||||
|
||||
bool InitMap(const std::string &fname, VMapManager2 *vm);
|
||||
void UnloadMap(VMapManager2 *vm);
|
||||
bool LoadMapTile(uint32 tileX, uint32 tileY, VMapManager2 *vm);
|
||||
void UnloadMapTile(uint32 tileX, uint32 tileY, VMapManager2 *vm);
|
||||
bool isTiled() const { return iIsTiled; }
|
||||
uint32 numLoadedTiles() const { return iLoadedTiles.size(); }
|
||||
};
|
||||
|
||||
struct AreaInfo
|
||||
{
|
||||
AreaInfo(): result(false), ground_Z(-G3D::inf()) {};
|
||||
bool result;
|
||||
float ground_Z;
|
||||
uint32 flags;
|
||||
int32 adtId;
|
||||
int32 rootId;
|
||||
int32 groupId;
|
||||
};
|
||||
} // VMAP
|
||||
|
||||
#endif // _MAPTREE_H
|
||||
@@ -0,0 +1,219 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2010 MaNGOS <http://getmangos.com/>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public 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 "ModelInstance.h"
|
||||
#include "WorldModel.h"
|
||||
#include "MapTree.h"
|
||||
|
||||
using G3D::Vector3;
|
||||
using G3D::Ray;
|
||||
|
||||
namespace VMAP
|
||||
{
|
||||
ModelInstance::ModelInstance(const ModelSpawn &spawn, WorldModel *model): ModelSpawn(spawn), iModel(model)
|
||||
{
|
||||
iInvRot = G3D::Matrix3::fromEulerAnglesZYX(G3D::pi()*iRot.y/180.f, G3D::pi()*iRot.x/180.f, G3D::pi()*iRot.z/180.f).inverse();
|
||||
iInvScale = 1.f/iScale;
|
||||
}
|
||||
|
||||
bool ModelInstance::intersectRay(const G3D::Ray& pRay, float& pMaxDist, bool pStopAtFirstHit) const
|
||||
{
|
||||
if (!iModel)
|
||||
{
|
||||
//std::cout << "<object not loaded>\n";
|
||||
return false;
|
||||
}
|
||||
float time = pRay.intersectionTime(iBound);
|
||||
if (time == G3D::inf())
|
||||
{
|
||||
// std::cout << "Ray does not hit '" << name << "'\n";
|
||||
|
||||
return false;
|
||||
}
|
||||
// std::cout << "Ray crosses bound of '" << name << "'\n";
|
||||
/* std::cout << "ray from:" << pRay.origin().x << ", " << pRay.origin().y << ", " << pRay.origin().z
|
||||
<< " dir:" << pRay.direction().x << ", " << pRay.direction().y << ", " << pRay.direction().z
|
||||
<< " t/tmax:" << time << "/" << pMaxDist;
|
||||
std::cout << "\nBound lo:" << iBound.low().x << ", " << iBound.low().y << ", " << iBound.low().z << " hi: "
|
||||
<< iBound.high().x << ", " << iBound.high().y << ", " << iBound.high().z << std::endl; */
|
||||
// child bounds are defined in object space:
|
||||
Vector3 p = iInvRot * (pRay.origin() - iPos) * iInvScale;
|
||||
Ray modRay(p, iInvRot * pRay.direction());
|
||||
float distance = pMaxDist * iInvScale;
|
||||
bool hit = iModel->IntersectRay(modRay, distance, pStopAtFirstHit);
|
||||
distance *= iScale;
|
||||
pMaxDist = distance;
|
||||
return hit;
|
||||
}
|
||||
|
||||
void ModelInstance::intersectPoint(const G3D::Vector3& p, AreaInfo &info) const
|
||||
{
|
||||
if (!iModel)
|
||||
{
|
||||
#ifdef VMAP_DEBUG
|
||||
std::cout << "<object not loaded>\n";
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
// M2 files don't contain area info, only WMO files
|
||||
if (flags & MOD_M2)
|
||||
return;
|
||||
if (!iBound.contains(p))
|
||||
return;
|
||||
// child bounds are defined in object space:
|
||||
Vector3 pModel = iInvRot * (p - iPos) * iInvScale;
|
||||
Vector3 zDirModel = iInvRot * Vector3(0.f, 0.f, -1.f);
|
||||
float zDist;
|
||||
if (iModel->IntersectPoint(pModel, zDirModel, zDist, info))
|
||||
{
|
||||
Vector3 modelGround = pModel + zDist * zDirModel;
|
||||
// Transform back to world space. Note that:
|
||||
// Mat * vec == vec * Mat.transpose()
|
||||
// and for rotation matrices: Mat.inverse() == Mat.transpose()
|
||||
float world_Z = ((modelGround * iInvRot) * iScale + iPos).z;
|
||||
if (info.ground_Z < world_Z)
|
||||
{
|
||||
info.ground_Z = world_Z;
|
||||
info.adtId = adtId;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool ModelInstance::GetLocationInfo(const G3D::Vector3& p, LocationInfo &info) const
|
||||
{
|
||||
if (!iModel)
|
||||
{
|
||||
#ifdef VMAP_DEBUG
|
||||
std::cout << "<object not loaded>\n";
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
// M2 files don't contain area info, only WMO files
|
||||
if (flags & MOD_M2)
|
||||
return false;
|
||||
if (!iBound.contains(p))
|
||||
return false;
|
||||
// child bounds are defined in object space:
|
||||
Vector3 pModel = iInvRot * (p - iPos) * iInvScale;
|
||||
Vector3 zDirModel = iInvRot * Vector3(0.f, 0.f, -1.f);
|
||||
float zDist;
|
||||
if (iModel->GetLocationInfo(pModel, zDirModel, zDist, info))
|
||||
{
|
||||
Vector3 modelGround = pModel + zDist * zDirModel;
|
||||
// Transform back to world space. Note that:
|
||||
// Mat * vec == vec * Mat.transpose()
|
||||
// and for rotation matrices: Mat.inverse() == Mat.transpose()
|
||||
float world_Z = ((modelGround * iInvRot) * iScale + iPos).z;
|
||||
if (info.ground_Z < world_Z) // hm...could it be handled automatically with zDist at intersection?
|
||||
{
|
||||
info.ground_Z = world_Z;
|
||||
info.hitInstance = this;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ModelInstance::GetLiquidLevel(const G3D::Vector3& p, LocationInfo &info, float &liqHeight) const
|
||||
{
|
||||
// child bounds are defined in object space:
|
||||
Vector3 pModel = iInvRot * (p - iPos) * iInvScale;
|
||||
//Vector3 zDirModel = iInvRot * Vector3(0.f, 0.f, -1.f);
|
||||
float zDist;
|
||||
if (info.hitModel->GetLiquidLevel(pModel, zDist))
|
||||
{
|
||||
// calculate world height (zDist in model coords):
|
||||
// assume WMO not tilted (wouldn't make much sense anyway)
|
||||
liqHeight = zDist * iScale + iPos.z;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ModelSpawn::readFromFile(FILE *rf, ModelSpawn &spawn)
|
||||
{
|
||||
uint32 check=0, nameLen;
|
||||
check += fread(&spawn.flags, sizeof(uint32), 1, rf);
|
||||
// EoF?
|
||||
if (!check)
|
||||
{
|
||||
if (ferror(rf))
|
||||
std::cout << "Error reading ModelSpawn!\n";
|
||||
return false;
|
||||
}
|
||||
check += fread(&spawn.adtId, sizeof(uint16), 1, rf);
|
||||
check += fread(&spawn.ID, sizeof(uint32), 1, rf);
|
||||
check += fread(&spawn.iPos, sizeof(float), 3, rf);
|
||||
check += fread(&spawn.iRot, sizeof(float), 3, rf);
|
||||
check += fread(&spawn.iScale, sizeof(float), 1, rf);
|
||||
bool has_bound = (spawn.flags & MOD_HAS_BOUND);
|
||||
if (has_bound) // only WMOs have bound in MPQ, only available after computation
|
||||
{
|
||||
Vector3 bLow, bHigh;
|
||||
check += fread(&bLow, sizeof(float), 3, rf);
|
||||
check += fread(&bHigh, sizeof(float), 3, rf);
|
||||
spawn.iBound = G3D::AABox(bLow, bHigh);
|
||||
}
|
||||
check += fread(&nameLen, sizeof(uint32), 1, rf);
|
||||
if(check != (has_bound ? 17 : 11))
|
||||
{
|
||||
std::cout << "Error reading ModelSpawn!\n";
|
||||
return false;
|
||||
}
|
||||
char nameBuff[500];
|
||||
if (nameLen>500) // file names should never be that long, must be file error
|
||||
{
|
||||
std::cout << "Error reading ModelSpawn, file name too long!\n";
|
||||
return false;
|
||||
}
|
||||
check = fread(nameBuff, sizeof(char), nameLen, rf);
|
||||
if (check != nameLen)
|
||||
{
|
||||
std::cout << "Error reading ModelSpawn!\n";
|
||||
return false;
|
||||
}
|
||||
spawn.name = std::string(nameBuff, nameLen);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ModelSpawn::writeToFile(FILE *wf, const ModelSpawn &spawn)
|
||||
{
|
||||
uint32 check=0;
|
||||
check += fwrite(&spawn.flags, sizeof(uint32), 1, wf);
|
||||
check += fwrite(&spawn.adtId, sizeof(uint16), 1, wf);
|
||||
check += fwrite(&spawn.ID, sizeof(uint32), 1, wf);
|
||||
check += fwrite(&spawn.iPos, sizeof(float), 3, wf);
|
||||
check += fwrite(&spawn.iRot, sizeof(float), 3, wf);
|
||||
check += fwrite(&spawn.iScale, sizeof(float), 1, wf);
|
||||
bool has_bound = (spawn.flags & MOD_HAS_BOUND);
|
||||
if(has_bound) // only WMOs have bound in MPQ, only available after computation
|
||||
{
|
||||
check += fwrite(&spawn.iBound.low(), sizeof(float), 3, wf);
|
||||
check += fwrite(&spawn.iBound.high(), sizeof(float), 3, wf);
|
||||
}
|
||||
uint32 nameLen = spawn.name.length();
|
||||
check += fwrite(&nameLen, sizeof(uint32), 1, wf);
|
||||
if(check != (has_bound ? 17 : 11)) return false;
|
||||
check = fwrite(spawn.name.c_str(), sizeof(char), nameLen, wf);
|
||||
if(check != nameLen) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,81 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2010 MaNGOS <http://getmangos.com/>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public 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 _MODELINSTANCE_H_
|
||||
#define _MODELINSTANCE_H_
|
||||
|
||||
#include <G3D/Matrix3.h>
|
||||
#include <G3D/Vector3.h>
|
||||
#include <G3D/AABox.h>
|
||||
#include <G3D/Ray.h>
|
||||
|
||||
#include "Platform/Define.h"
|
||||
|
||||
namespace VMAP
|
||||
{
|
||||
class WorldModel;
|
||||
struct AreaInfo;
|
||||
struct LocationInfo;
|
||||
|
||||
enum ModelFlags
|
||||
{
|
||||
MOD_M2 = 1,
|
||||
MOD_WORLDSPAWN = 1<<1,
|
||||
MOD_HAS_BOUND = 1<<2
|
||||
};
|
||||
|
||||
class ModelSpawn
|
||||
{
|
||||
public:
|
||||
//mapID, tileX, tileY, Flags, ID, Pos, Rot, Scale, Bound_lo, Bound_hi, name
|
||||
uint32 flags;
|
||||
uint16 adtId;
|
||||
uint32 ID;
|
||||
G3D::Vector3 iPos;
|
||||
G3D::Vector3 iRot;
|
||||
float iScale;
|
||||
G3D::AABox iBound;
|
||||
std::string name;
|
||||
bool operator==(const ModelSpawn &other) const { return ID == other.ID; }
|
||||
//uint32 hashCode() const { return ID; }
|
||||
// temp?
|
||||
const G3D::AABox& getBounds() const { return iBound; }
|
||||
|
||||
|
||||
static bool readFromFile(FILE *rf, ModelSpawn &spawn);
|
||||
static bool writeToFile(FILE *rw, const ModelSpawn &spawn);
|
||||
};
|
||||
|
||||
class ModelInstance: public ModelSpawn
|
||||
{
|
||||
public:
|
||||
ModelInstance(): iModel(0) {}
|
||||
ModelInstance(const ModelSpawn &spawn, WorldModel *model);
|
||||
void setUnloaded() { iModel = 0; }
|
||||
bool intersectRay(const G3D::Ray& pRay, float& pMaxDist, bool pStopAtFirstHit) const;
|
||||
void intersectPoint(const G3D::Vector3& p, AreaInfo &info) const;
|
||||
bool GetLocationInfo(const G3D::Vector3& p, LocationInfo &info) const;
|
||||
bool GetLiquidLevel(const G3D::Vector3& p, LocationInfo &info, float &liqHeight) const;
|
||||
protected:
|
||||
G3D::Matrix3 iInvRot;
|
||||
float iInvScale;
|
||||
WorldModel *iModel;
|
||||
};
|
||||
} // namespace VMAP
|
||||
|
||||
#endif // _MODELINSTANCE
|
||||
@@ -0,0 +1,494 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2010 MaNGOS <http://getmangos.com/>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public 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 "WorldModel.h"
|
||||
#include "TileAssembler.h"
|
||||
#include "MapTree.h"
|
||||
#include "BIH.h"
|
||||
#include "VMapDefinitions.h"
|
||||
|
||||
#include <set>
|
||||
#include <iomanip>
|
||||
#include <sstream>
|
||||
#include <iomanip>
|
||||
|
||||
using G3D::Vector3;
|
||||
using G3D::AABox;
|
||||
using G3D::inf;
|
||||
using std::pair;
|
||||
|
||||
template<> struct BoundsTrait<VMAP::ModelSpawn*>
|
||||
{
|
||||
static void getBounds(const VMAP::ModelSpawn* const &obj, G3D::AABox& out) { out = obj->getBounds(); }
|
||||
};
|
||||
|
||||
namespace VMAP
|
||||
{
|
||||
bool readChunk(FILE *rf, char *dest, const char *compare, uint32 len)
|
||||
{
|
||||
if (fread(dest, sizeof(char), len, rf) != len) return false;
|
||||
return memcmp(dest, compare, len) == 0;
|
||||
}
|
||||
|
||||
Vector3 ModelPosition::transform(const Vector3& pIn) const
|
||||
{
|
||||
Vector3 out = pIn * iScale;
|
||||
out = iRotation * out;
|
||||
return(out);
|
||||
}
|
||||
|
||||
//=================================================================
|
||||
|
||||
TileAssembler::TileAssembler(const std::string& pSrcDirName, const std::string& pDestDirName)
|
||||
{
|
||||
iCurrentUniqueNameId = 0;
|
||||
iFilterMethod = NULL;
|
||||
iSrcDir = pSrcDirName;
|
||||
iDestDir = pDestDirName;
|
||||
//mkdir(iDestDir);
|
||||
//init();
|
||||
}
|
||||
|
||||
TileAssembler::~TileAssembler()
|
||||
{
|
||||
//delete iCoordModelMapping;
|
||||
}
|
||||
|
||||
bool TileAssembler::convertWorld2()
|
||||
{
|
||||
std::set<std::string> spawnedModelFiles;
|
||||
bool success = readMapSpawns();
|
||||
if (!success)
|
||||
return false;
|
||||
|
||||
// export Map data
|
||||
for (MapData::iterator map_iter = mapData.begin(); map_iter != mapData.end() && success; ++map_iter)
|
||||
{
|
||||
// build global map tree
|
||||
std::vector<ModelSpawn*> mapSpawns;
|
||||
UniqueEntryMap::iterator entry;
|
||||
for (entry = map_iter->second->UniqueEntries.begin(); entry != map_iter->second->UniqueEntries.end(); ++entry)
|
||||
{
|
||||
// M2 models don't have a bound set in WDT/ADT placement data, i still think they're not used for LoS at all on retail
|
||||
if (entry->second.flags & MOD_M2)
|
||||
{
|
||||
if (!calculateTransformedBound(entry->second))
|
||||
break;
|
||||
}
|
||||
else if (entry->second.flags & MOD_WORLDSPAWN) // WMO maps and terrain maps use different origin, so we need to adapt :/
|
||||
{
|
||||
// TODO: remove extractor hack and uncomment below line:
|
||||
//entry->second.iPos += Vector3(533.33333f*32, 533.33333f*32, 0.f);
|
||||
entry->second.iBound = entry->second.iBound + Vector3(533.33333f*32, 533.33333f*32, 0.f);
|
||||
}
|
||||
mapSpawns.push_back(&(entry->second));
|
||||
spawnedModelFiles.insert(entry->second.name);
|
||||
}
|
||||
|
||||
BIH pTree;
|
||||
pTree.build(mapSpawns, BoundsTrait<ModelSpawn*>::getBounds);
|
||||
|
||||
// ===> possibly move this code to StaticMapTree class
|
||||
std::map<uint32, uint32> modelNodeIdx;
|
||||
for (uint32 i=0; i<mapSpawns.size(); ++i)
|
||||
modelNodeIdx.insert(pair<uint32, uint32>(mapSpawns[i]->ID, i));
|
||||
if (!modelNodeIdx.empty())
|
||||
printf("min GUID: %u, max GUID: %u\n", modelNodeIdx.begin()->first, modelNodeIdx.rbegin()->first);
|
||||
|
||||
// write map tree file
|
||||
std::stringstream mapfilename;
|
||||
mapfilename << iDestDir << "/" << std::setfill('0') << std::setw(3) << map_iter->first << ".vmtree";
|
||||
FILE *mapfile = fopen(mapfilename.str().c_str(), "wb");
|
||||
if (!mapfile)
|
||||
{
|
||||
success = false;
|
||||
printf("Cannot open %s\n", mapfilename.str().c_str());
|
||||
break;
|
||||
}
|
||||
|
||||
//general info
|
||||
if (success && fwrite(VMAP_MAGIC, 1, 8, mapfile) != 8) success = false;
|
||||
uint32 globalTileID = StaticMapTree::packTileID(65, 65);
|
||||
pair<TileMap::iterator, TileMap::iterator> globalRange = map_iter->second->TileEntries.equal_range(globalTileID);
|
||||
char isTiled = globalRange.first == globalRange.second; // only maps without terrain (tiles) have global WMO
|
||||
if (success && fwrite(&isTiled, sizeof(char), 1, mapfile) != 1) success = false;
|
||||
// Nodes
|
||||
if (success && fwrite("NODE", 4, 1, mapfile) != 1) success = false;
|
||||
if (success) success = pTree.writeToFile(mapfile);
|
||||
// global map spawns (WDT), if any (most instances)
|
||||
if (success && fwrite("GOBJ", 4, 1, mapfile) != 1) success = false;
|
||||
|
||||
for (TileMap::iterator glob=globalRange.first; glob != globalRange.second && success; ++glob)
|
||||
{
|
||||
success = ModelSpawn::writeToFile(mapfile, map_iter->second->UniqueEntries[glob->second]);
|
||||
}
|
||||
|
||||
fclose(mapfile);
|
||||
|
||||
// <====
|
||||
|
||||
// write map tile files, similar to ADT files, only with extra BSP tree node info
|
||||
TileMap &tileEntries = map_iter->second->TileEntries;
|
||||
TileMap::iterator tile;
|
||||
for (tile = tileEntries.begin(); tile != tileEntries.end(); ++tile)
|
||||
{
|
||||
const ModelSpawn &spawn = map_iter->second->UniqueEntries[tile->second];
|
||||
if (spawn.flags & MOD_WORLDSPAWN) // WDT spawn, saved as tile 65/65 currently...
|
||||
continue;
|
||||
uint32 nSpawns = tileEntries.count(tile->first);
|
||||
std::stringstream tilefilename;
|
||||
tilefilename.fill('0');
|
||||
tilefilename << iDestDir << "/" << std::setw(3) << map_iter->first << "_";
|
||||
uint32 x, y;
|
||||
StaticMapTree::unpackTileID(tile->first, x, y);
|
||||
tilefilename << std::setw(2) << x << "_" << std::setw(2) << y << ".vmtile";
|
||||
FILE *tilefile = fopen(tilefilename.str().c_str(), "wb");
|
||||
// write number of tile spawns
|
||||
if (success && fwrite(&nSpawns, sizeof(uint32), 1, tilefile) != 1) success = false;
|
||||
// write tile spawns
|
||||
for (uint32 s=0; s<nSpawns; ++s)
|
||||
{
|
||||
if (s)
|
||||
++tile;
|
||||
const ModelSpawn &spawn2 = map_iter->second->UniqueEntries[tile->second];
|
||||
success = success && ModelSpawn::writeToFile(tilefile, spawn2);
|
||||
// MapTree nodes to update when loading tile:
|
||||
std::map<uint32, uint32>::iterator nIdx = modelNodeIdx.find(spawn2.ID);
|
||||
if (success && fwrite(&nIdx->second, sizeof(uint32), 1, tilefile) != 1) success = false;
|
||||
}
|
||||
fclose(tilefile);
|
||||
}
|
||||
// break; //test, extract only first map; TODO: remvoe this line
|
||||
}
|
||||
|
||||
// export objects
|
||||
std::cout << "\nConverting Model Files" << std::endl;
|
||||
for (std::set<std::string>::iterator mfile = spawnedModelFiles.begin(); mfile != spawnedModelFiles.end(); ++mfile)
|
||||
{
|
||||
std::cout << "Converting " << *mfile << std::endl;
|
||||
if (!convertRawFile(*mfile))
|
||||
{
|
||||
std::cout << "error converting " << *mfile << std::endl;
|
||||
success = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//cleanup:
|
||||
for (MapData::iterator map_iter = mapData.begin(); map_iter != mapData.end(); ++map_iter)
|
||||
{
|
||||
delete map_iter->second;
|
||||
}
|
||||
return success;
|
||||
}
|
||||
|
||||
bool TileAssembler::readMapSpawns()
|
||||
{
|
||||
std::string fname = iSrcDir + "/dir_bin";
|
||||
FILE *dirf = fopen(fname.c_str(), "rb");
|
||||
if (!dirf)
|
||||
{
|
||||
printf("Could not read dir_bin file!\n");
|
||||
return false;
|
||||
}
|
||||
printf("Read coordinate mapping...\n");
|
||||
uint32 mapID, tileX, tileY, check=0;
|
||||
G3D::Vector3 v1, v2;
|
||||
ModelSpawn spawn;
|
||||
while (!feof(dirf))
|
||||
{
|
||||
check = 0;
|
||||
// read mapID, tileX, tileY, Flags, adtID, ID, Pos, Rot, Scale, Bound_lo, Bound_hi, name
|
||||
check += fread(&mapID, sizeof(uint32), 1, dirf);
|
||||
if (check == 0) // EoF...
|
||||
break;
|
||||
check += fread(&tileX, sizeof(uint32), 1, dirf);
|
||||
check += fread(&tileY, sizeof(uint32), 1, dirf);
|
||||
if (!ModelSpawn::readFromFile(dirf, spawn))
|
||||
break;
|
||||
|
||||
MapSpawns *current;
|
||||
MapData::iterator map_iter = mapData.find(mapID);
|
||||
if (map_iter == mapData.end())
|
||||
{
|
||||
printf("spawning Map %d\n", mapID);
|
||||
mapData[mapID] = current = new MapSpawns();
|
||||
}
|
||||
else current = (*map_iter).second;
|
||||
current->UniqueEntries.insert(pair<uint32, ModelSpawn>(spawn.ID, spawn));
|
||||
current->TileEntries.insert(pair<uint32, uint32>(StaticMapTree::packTileID(tileX, tileY), spawn.ID));
|
||||
}
|
||||
bool success = (ferror(dirf) == 0);
|
||||
fclose(dirf);
|
||||
return success;
|
||||
}
|
||||
|
||||
bool TileAssembler::calculateTransformedBound(ModelSpawn &spawn)
|
||||
{
|
||||
std::string modelFilename = iSrcDir + "/" + spawn.name;
|
||||
ModelPosition modelPosition;
|
||||
modelPosition.iDir = spawn.iRot;
|
||||
modelPosition.iScale = spawn.iScale;
|
||||
modelPosition.init();
|
||||
|
||||
FILE *rf = fopen(modelFilename.c_str(), "rb");
|
||||
if (!rf)
|
||||
{
|
||||
printf("ERROR: Can't open model file: %s\n", modelFilename.c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
AABox modelBound;
|
||||
bool boundEmpty=true;
|
||||
char ident[8];
|
||||
|
||||
int readOperation = 1;
|
||||
|
||||
// temporary use defines to simplify read/check code (close file and return at fail)
|
||||
#define READ_OR_RETURN(V,S) if(fread((V), (S), 1, rf) != 1) { \
|
||||
fclose(rf); printf("readfail, op = %i\n", readOperation); return(false); }readOperation++;
|
||||
#define CMP_OR_RETURN(V,S) if(strcmp((V),(S)) != 0) { \
|
||||
fclose(rf); printf("cmpfail, %s!=%s\n", V, S);return(false); }
|
||||
|
||||
READ_OR_RETURN(&ident, 8);
|
||||
CMP_OR_RETURN(ident, "VMAP003");
|
||||
|
||||
// we have to read one int. This is needed during the export and we have to skip it here
|
||||
uint32 tempNVectors;
|
||||
READ_OR_RETURN(&tempNVectors, sizeof(tempNVectors));
|
||||
|
||||
uint32 groups, wmoRootId;
|
||||
char blockId[5];
|
||||
blockId[4] = 0;
|
||||
int blocksize;
|
||||
float *vectorarray = 0;
|
||||
|
||||
READ_OR_RETURN(&groups, sizeof(uint32));
|
||||
READ_OR_RETURN(&wmoRootId, sizeof(uint32));
|
||||
if (groups != 1) printf("Warning: '%s' does not seem to be a M2 model!\n", modelFilename.c_str());
|
||||
|
||||
for (uint32 g=0; g<groups; ++g) // should be only one for M2 files...
|
||||
{
|
||||
fseek(rf, 3*sizeof(uint32) + 6*sizeof(float), SEEK_CUR);
|
||||
|
||||
READ_OR_RETURN(&blockId, 4);
|
||||
CMP_OR_RETURN(blockId, "GRP ");
|
||||
READ_OR_RETURN(&blocksize, sizeof(int));
|
||||
fseek(rf, blocksize, SEEK_CUR);
|
||||
|
||||
// ---- indexes
|
||||
READ_OR_RETURN(&blockId, 4);
|
||||
CMP_OR_RETURN(blockId, "INDX");
|
||||
READ_OR_RETURN(&blocksize, sizeof(int));
|
||||
fseek(rf, blocksize, SEEK_CUR);
|
||||
|
||||
// ---- vectors
|
||||
READ_OR_RETURN(&blockId, 4);
|
||||
CMP_OR_RETURN(blockId, "VERT");
|
||||
READ_OR_RETURN(&blocksize, sizeof(int));
|
||||
uint32 nvectors;
|
||||
READ_OR_RETURN(&nvectors, sizeof(uint32));
|
||||
|
||||
if (nvectors >0)
|
||||
{
|
||||
vectorarray = new float[nvectors*3];
|
||||
READ_OR_RETURN(vectorarray, nvectors*sizeof(float)*3);
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cout << "error: model '" << spawn.name << "' has no geometry!" << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
for (uint32 i=0, indexNo=0; indexNo<nvectors; indexNo++, i+=3)
|
||||
{
|
||||
Vector3 v = Vector3(vectorarray[i+0], vectorarray[i+1], vectorarray[i+2]);
|
||||
v = modelPosition.transform(v);
|
||||
|
||||
if (boundEmpty)
|
||||
modelBound = AABox(v, v), boundEmpty=false;
|
||||
else
|
||||
modelBound.merge(v);
|
||||
}
|
||||
delete[] vectorarray;
|
||||
// drop of temporary use defines
|
||||
#undef READ_OR_RETURN
|
||||
#undef CMP_OR_RETURN
|
||||
}
|
||||
spawn.iBound = modelBound + spawn.iPos;
|
||||
spawn.flags |= MOD_HAS_BOUND;
|
||||
fclose(rf);
|
||||
return true;
|
||||
}
|
||||
|
||||
struct WMOLiquidHeader
|
||||
{
|
||||
int xverts, yverts, xtiles, ytiles;
|
||||
float pos_x;
|
||||
float pos_y;
|
||||
float pos_z;
|
||||
short type;
|
||||
};
|
||||
//=================================================================
|
||||
bool TileAssembler::convertRawFile(const std::string& pModelFilename)
|
||||
{
|
||||
bool success = true;
|
||||
std::string filename = iSrcDir;
|
||||
if (filename.length() >0)
|
||||
filename.append("/");
|
||||
filename.append(pModelFilename);
|
||||
FILE *rf = fopen(filename.c_str(), "rb");
|
||||
|
||||
if (!rf)
|
||||
{
|
||||
printf("ERROR: Can't open model file in form: %s",pModelFilename.c_str());
|
||||
printf("... or form: %s",filename.c_str() );
|
||||
return false;
|
||||
}
|
||||
|
||||
char ident[8];
|
||||
|
||||
int readOperation = 1;
|
||||
|
||||
// temporary use defines to simplify read/check code (close file and return at fail)
|
||||
#define READ_OR_RETURN(V,S) if(fread((V), (S), 1, rf) != 1) { \
|
||||
fclose(rf); printf("readfail, op = %i\n", readOperation); return(false); }readOperation++;
|
||||
#define CMP_OR_RETURN(V,S) if(strcmp((V),(S)) != 0) { \
|
||||
fclose(rf); printf("cmpfail, %s!=%s\n", V, S);return(false); }
|
||||
|
||||
READ_OR_RETURN(&ident, 8);
|
||||
CMP_OR_RETURN(ident, "VMAP003");
|
||||
|
||||
// we have to read one int. This is needed during the export and we have to skip it here
|
||||
uint32 tempNVectors;
|
||||
READ_OR_RETURN(&tempNVectors, sizeof(tempNVectors));
|
||||
|
||||
uint32 groups;
|
||||
uint32 RootWMOID;
|
||||
char blockId[5];
|
||||
blockId[4] = 0;
|
||||
int blocksize;
|
||||
|
||||
READ_OR_RETURN(&groups, sizeof(uint32));
|
||||
READ_OR_RETURN(&RootWMOID, sizeof(uint32));
|
||||
|
||||
std::vector<GroupModel> groupsArray;
|
||||
|
||||
for (uint32 g=0; g<groups; ++g)
|
||||
{
|
||||
std::vector<MeshTriangle> triangles;
|
||||
std::vector<Vector3> vertexArray;
|
||||
|
||||
uint32 mogpflags, GroupWMOID;
|
||||
READ_OR_RETURN(&mogpflags, sizeof(uint32));
|
||||
READ_OR_RETURN(&GroupWMOID, sizeof(uint32));
|
||||
|
||||
float bbox1[3], bbox2[3];
|
||||
READ_OR_RETURN(bbox1, sizeof(float)*3);
|
||||
READ_OR_RETURN(bbox2, sizeof(float)*3);
|
||||
|
||||
uint32 liquidflags;
|
||||
READ_OR_RETURN(&liquidflags, sizeof(uint32));
|
||||
|
||||
// will this ever be used? what is it good for anyway??
|
||||
uint32 branches;
|
||||
READ_OR_RETURN(&blockId, 4);
|
||||
CMP_OR_RETURN(blockId, "GRP ");
|
||||
READ_OR_RETURN(&blocksize, sizeof(int));
|
||||
READ_OR_RETURN(&branches, sizeof(uint32));
|
||||
for (uint32 b=0; b<branches; ++b)
|
||||
{
|
||||
uint32 indexes;
|
||||
// indexes for each branch (not used jet)
|
||||
READ_OR_RETURN(&indexes, sizeof(uint32));
|
||||
}
|
||||
|
||||
// ---- indexes
|
||||
READ_OR_RETURN(&blockId, 4);
|
||||
CMP_OR_RETURN(blockId, "INDX");
|
||||
READ_OR_RETURN(&blocksize, sizeof(int));
|
||||
uint32 nindexes;
|
||||
READ_OR_RETURN(&nindexes, sizeof(uint32));
|
||||
if (nindexes >0)
|
||||
{
|
||||
uint16 *indexarray = new uint16[nindexes];
|
||||
READ_OR_RETURN(indexarray, nindexes*sizeof(uint16));
|
||||
for (uint32 i=0; i<nindexes; i+=3)
|
||||
{
|
||||
triangles.push_back(MeshTriangle(indexarray[i], indexarray[i+1], indexarray[i+2]));
|
||||
}
|
||||
delete[] indexarray;
|
||||
}
|
||||
|
||||
// ---- vectors
|
||||
READ_OR_RETURN(&blockId, 4);
|
||||
CMP_OR_RETURN(blockId, "VERT");
|
||||
READ_OR_RETURN(&blocksize, sizeof(int));
|
||||
uint32 nvectors;
|
||||
READ_OR_RETURN(&nvectors, sizeof(uint32));
|
||||
|
||||
if (nvectors >0)
|
||||
{
|
||||
float *vectorarray = new float[nvectors*3];
|
||||
READ_OR_RETURN(vectorarray, nvectors*sizeof(float)*3);
|
||||
for (uint32 i=0; i<nvectors; ++i)
|
||||
{
|
||||
vertexArray.push_back( Vector3(vectorarray + 3*i) );
|
||||
}
|
||||
delete[] vectorarray;
|
||||
}
|
||||
// ----- liquid
|
||||
WmoLiquid *liquid = 0;
|
||||
if (liquidflags& 1)
|
||||
{
|
||||
WMOLiquidHeader hlq;
|
||||
READ_OR_RETURN(&blockId, 4);
|
||||
CMP_OR_RETURN(blockId, "LIQU");
|
||||
READ_OR_RETURN(&blocksize, sizeof(int));
|
||||
READ_OR_RETURN(&hlq, sizeof(WMOLiquidHeader));
|
||||
liquid = new WmoLiquid(hlq.xtiles, hlq.ytiles, Vector3(hlq.pos_x, hlq.pos_y, hlq.pos_z), hlq.type);
|
||||
uint32 size = hlq.xverts*hlq.yverts;
|
||||
READ_OR_RETURN(liquid->GetHeightStorage(), size*sizeof(float));
|
||||
size = hlq.xtiles*hlq.ytiles;
|
||||
READ_OR_RETURN(liquid->GetFlagsStorage(), size);
|
||||
}
|
||||
|
||||
groupsArray.push_back(GroupModel(mogpflags, GroupWMOID, AABox(Vector3(bbox1), Vector3(bbox2))));
|
||||
groupsArray.back().setMeshData(vertexArray, triangles);
|
||||
groupsArray.back().setLiquidData(liquid);
|
||||
|
||||
// drop of temporary use defines
|
||||
#undef READ_OR_RETURN
|
||||
#undef CMP_OR_RETURN
|
||||
|
||||
}
|
||||
fclose(rf);
|
||||
|
||||
// write WorldModel
|
||||
WorldModel model;
|
||||
model.setRootWmoID(RootWMOID);
|
||||
if (groupsArray.size())
|
||||
{
|
||||
model.setGroupModels(groupsArray);
|
||||
success = model.writeFile(iDestDir + "/" + pModelFilename + ".vmo");
|
||||
}
|
||||
|
||||
//std::cout << "readRawFile2: '" << pModelFilename << "' tris: " << nElements << " nodes: " << nNodes << std::endl;
|
||||
return success;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,89 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2010 MaNGOS <http://getmangos.com/>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public 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 _TILEASSEMBLER_H_
|
||||
#define _TILEASSEMBLER_H_
|
||||
|
||||
#include <G3D/Vector3.h>
|
||||
#include <G3D/Matrix3.h>
|
||||
#include <map>
|
||||
|
||||
#include "ModelInstance.h"
|
||||
|
||||
namespace VMAP
|
||||
{
|
||||
/**
|
||||
This Class is used to convert raw vector data into balanced BSP-Trees.
|
||||
To start the conversion call convertWorld().
|
||||
*/
|
||||
//===============================================
|
||||
|
||||
class ModelPosition
|
||||
{
|
||||
private:
|
||||
G3D::Matrix3 iRotation;
|
||||
public:
|
||||
G3D::Vector3 iPos;
|
||||
G3D::Vector3 iDir;
|
||||
float iScale;
|
||||
void init()
|
||||
{
|
||||
iRotation = G3D::Matrix3::fromEulerAnglesZYX(G3D::pi()*iDir.y/180.f, G3D::pi()*iDir.x/180.f, G3D::pi()*iDir.z/180.f);
|
||||
}
|
||||
G3D::Vector3 transform(const G3D::Vector3& pIn) const;
|
||||
void moveToBasePos(const G3D::Vector3& pBasePos) { iPos -= pBasePos; }
|
||||
};
|
||||
|
||||
typedef std::map<uint32, ModelSpawn> UniqueEntryMap;
|
||||
typedef std::multimap<uint32, uint32> TileMap;
|
||||
|
||||
struct MapSpawns
|
||||
{
|
||||
UniqueEntryMap UniqueEntries;
|
||||
TileMap TileEntries;
|
||||
};
|
||||
|
||||
typedef std::map<uint32, MapSpawns*> MapData;
|
||||
//===============================================
|
||||
|
||||
class TileAssembler
|
||||
{
|
||||
private:
|
||||
std::string iDestDir;
|
||||
std::string iSrcDir;
|
||||
bool (*iFilterMethod)(char *pName);
|
||||
G3D::Table<std::string, unsigned int > iUniqueNameIds;
|
||||
unsigned int iCurrentUniqueNameId;
|
||||
MapData mapData;
|
||||
|
||||
public:
|
||||
TileAssembler(const std::string& pSrcDirName, const std::string& pDestDirName);
|
||||
virtual ~TileAssembler();
|
||||
|
||||
bool convertWorld2();
|
||||
bool readMapSpawns();
|
||||
bool calculateTransformedBound(ModelSpawn &spawn);
|
||||
|
||||
bool convertRawFile(const std::string& pModelFilename);
|
||||
void setModelNameFilterMethod(bool (*pFilterMethod)(char *pName)) { iFilterMethod = pFilterMethod; }
|
||||
std::string getDirEntryNameFromModName(unsigned int pMapId, const std::string& pModPosName);
|
||||
unsigned int getUniqueNameId(const std::string pName);
|
||||
};
|
||||
|
||||
} // VMAP
|
||||
#endif /*_TILEASSEMBLER_H_*/
|
||||
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2010 MaNGOS <http://getmangos.com/>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public 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 _VMAPDEFINITIONS_H
|
||||
#define _VMAPDEFINITIONS_H
|
||||
#include <cstring>
|
||||
|
||||
#define LIQUID_TILE_SIZE (533.333f / 128.f)
|
||||
|
||||
namespace VMAP
|
||||
{
|
||||
//=====================================
|
||||
#define MAX_CAN_FALL_DISTANCE 10.0f
|
||||
const char VMAP_MAGIC[] = "VMAP_3.0";
|
||||
|
||||
class VMapDefinitions
|
||||
{
|
||||
public:
|
||||
static float getMaxCanFallDistance() { return MAX_CAN_FALL_DISTANCE; }
|
||||
};
|
||||
|
||||
//======================================
|
||||
|
||||
// defined in TileAssembler.cpp currently...
|
||||
bool readChunk(FILE *rf, char *dest, const char *compare, uint32 len);
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,136 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2010 MaNGOS <http://getmangos.com/>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public 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 <sys/types.h>
|
||||
#include "VMapFactory.h"
|
||||
#include "VMapManager2.h"
|
||||
|
||||
using namespace G3D;
|
||||
|
||||
namespace VMAP
|
||||
{
|
||||
void chompAndTrim(std::string& str)
|
||||
{
|
||||
while(str.length() >0)
|
||||
{
|
||||
char lc = str[str.length()-1];
|
||||
if(lc == '\r' || lc == '\n' || lc == ' ' || lc == '"' || lc == '\'')
|
||||
{
|
||||
str = str.substr(0,str.length()-1);
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
while(str.length() >0)
|
||||
{
|
||||
char lc = str[0];
|
||||
if(lc == ' ' || lc == '"' || lc == '\'')
|
||||
{
|
||||
str = str.substr(1,str.length()-1);
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
IVMapManager *gVMapManager = 0;
|
||||
Table<unsigned int , bool>* iIgnoreSpellIds=0;
|
||||
|
||||
//===============================================
|
||||
// result false, if no more id are found
|
||||
|
||||
bool getNextId(const std::string& pString, unsigned int& pStartPos, unsigned int& pId)
|
||||
{
|
||||
bool result = false;
|
||||
unsigned int i;
|
||||
for(i=pStartPos;i<pString.size(); ++i)
|
||||
{
|
||||
if(pString[i] == ',')
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(i>pStartPos)
|
||||
{
|
||||
std::string idString = pString.substr(pStartPos, i-pStartPos);
|
||||
pStartPos = i+1;
|
||||
chompAndTrim(idString);
|
||||
pId = atoi(idString.c_str());
|
||||
result = true;
|
||||
}
|
||||
return(result);
|
||||
}
|
||||
|
||||
//===============================================
|
||||
/**
|
||||
parameter: String of map ids. Delimiter = ","
|
||||
*/
|
||||
|
||||
void VMapFactory::preventSpellsFromBeingTestedForLoS(const char* pSpellIdString)
|
||||
{
|
||||
if(!iIgnoreSpellIds)
|
||||
iIgnoreSpellIds = new Table<unsigned int , bool>();
|
||||
if(pSpellIdString != NULL)
|
||||
{
|
||||
unsigned int pos =0;
|
||||
unsigned int id;
|
||||
std::string confString(pSpellIdString);
|
||||
chompAndTrim(confString);
|
||||
while(getNextId(confString, pos, id))
|
||||
{
|
||||
iIgnoreSpellIds->set(id, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//===============================================
|
||||
|
||||
bool VMapFactory::checkSpellForLoS(unsigned int pSpellId)
|
||||
{
|
||||
return(!iIgnoreSpellIds->containsKey(pSpellId));
|
||||
}
|
||||
|
||||
//===============================================
|
||||
// just return the instance
|
||||
IVMapManager* VMapFactory::createOrGetVMapManager()
|
||||
{
|
||||
if(gVMapManager == 0)
|
||||
gVMapManager= new VMapManager2(); // should be taken from config ... Please change if you like :-)
|
||||
return gVMapManager;
|
||||
}
|
||||
|
||||
//===============================================
|
||||
// delete all internal data structures
|
||||
void VMapFactory::clear()
|
||||
{
|
||||
if(iIgnoreSpellIds)
|
||||
{
|
||||
delete iIgnoreSpellIds;
|
||||
iIgnoreSpellIds = NULL;
|
||||
}
|
||||
if(gVMapManager)
|
||||
{
|
||||
delete gVMapManager;
|
||||
gVMapManager = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2010 MaNGOS <http://getmangos.com/>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public 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 _VMAPFACTORY_H
|
||||
#define _VMAPFACTORY_H
|
||||
|
||||
#include "IVMapManager.h"
|
||||
|
||||
/**
|
||||
This is the access point to the VMapManager.
|
||||
*/
|
||||
|
||||
namespace VMAP
|
||||
{
|
||||
//===========================================================
|
||||
|
||||
class VMapFactory
|
||||
{
|
||||
public:
|
||||
static IVMapManager* createOrGetVMapManager();
|
||||
static void clear();
|
||||
|
||||
static void preventSpellsFromBeingTestedForLoS(const char* pSpellIdString);
|
||||
static bool checkSpellForLoS(unsigned int pSpellId);
|
||||
};
|
||||
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,336 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2010 MaNGOS <http://getmangos.com/>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public 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 <iostream>
|
||||
#include <iomanip>
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
#include "VMapManager2.h"
|
||||
#include "MapTree.h"
|
||||
#include "ModelInstance.h"
|
||||
#include "WorldModel.h"
|
||||
#include "VMapDefinitions.h"
|
||||
|
||||
using G3D::Vector3;
|
||||
|
||||
namespace VMAP
|
||||
{
|
||||
|
||||
//=========================================================
|
||||
|
||||
VMapManager2::VMapManager2()
|
||||
{
|
||||
}
|
||||
|
||||
//=========================================================
|
||||
|
||||
VMapManager2::~VMapManager2(void)
|
||||
{
|
||||
for (InstanceTreeMap::iterator i = iInstanceMapTrees.begin(); i != iInstanceMapTrees.end(); ++i)
|
||||
{
|
||||
delete i->second;
|
||||
}
|
||||
for (ModelFileMap::iterator i = iLoadedModelFiles.begin(); i != iLoadedModelFiles.end(); ++i)
|
||||
{
|
||||
delete i->second.getModel();
|
||||
}
|
||||
}
|
||||
|
||||
//=========================================================
|
||||
|
||||
Vector3 VMapManager2::convertPositionToInternalRep(float x, float y, float z) const
|
||||
{
|
||||
Vector3 pos;
|
||||
const float mid = 0.5 * 64.0 * 533.33333333f;
|
||||
pos.x = mid - x;
|
||||
pos.y = mid - y;
|
||||
pos.z = z;
|
||||
|
||||
return pos;
|
||||
}
|
||||
|
||||
//=========================================================
|
||||
|
||||
Vector3 VMapManager2::convertPositionToMangosRep(float x, float y, float z) const
|
||||
{
|
||||
Vector3 pos;
|
||||
const float mid = 0.5 * 64.0 * 533.33333333f;
|
||||
pos.x = mid - x;
|
||||
pos.y = mid - y;
|
||||
pos.z = z;
|
||||
|
||||
return pos;
|
||||
}
|
||||
//=========================================================
|
||||
|
||||
// move to MapTree too?
|
||||
std::string VMapManager2::getMapFileName(unsigned int pMapId)
|
||||
{
|
||||
std::stringstream fname;
|
||||
fname.width(3);
|
||||
fname << std::setfill('0') << pMapId << std::string(MAP_FILENAME_EXTENSION2);
|
||||
return fname.str();
|
||||
}
|
||||
|
||||
//=========================================================
|
||||
/**
|
||||
Block maps from being used.
|
||||
parameter: String of map ids. Delimiter = ","
|
||||
e.g.: "0,1,590"
|
||||
*/
|
||||
|
||||
void VMapManager2::preventMapsFromBeingUsed(const char* pMapIdString)
|
||||
{
|
||||
iIgnoreMapIds.clear();
|
||||
if (pMapIdString != NULL)
|
||||
{
|
||||
std::string map_str;
|
||||
std::stringstream map_ss;
|
||||
map_ss.str(std::string(pMapIdString));
|
||||
while (std::getline(map_ss, map_str, ','))
|
||||
{
|
||||
std::stringstream ss2(map_str);
|
||||
int map_num = -1;
|
||||
ss2 >> map_num;
|
||||
if (map_num >= 0)
|
||||
{
|
||||
std::cout << "ingoring Map " << map_num << " for VMaps\n";
|
||||
iIgnoreMapIds[map_num] = true;
|
||||
// unload map in case it is loaded
|
||||
unloadMap(map_num);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//=========================================================
|
||||
|
||||
int VMapManager2::loadMap(const char* pBasePath, unsigned int pMapId, int x, int y)
|
||||
{
|
||||
int result = VMAP_LOAD_RESULT_IGNORED;
|
||||
if (isMapLoadingEnabled() && !iIgnoreMapIds.count(pMapId))
|
||||
{
|
||||
if (_loadMap(pMapId, pBasePath, x, y))
|
||||
result = VMAP_LOAD_RESULT_OK;
|
||||
else
|
||||
result = VMAP_LOAD_RESULT_ERROR;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
//=========================================================
|
||||
// load one tile (internal use only)
|
||||
|
||||
bool VMapManager2::_loadMap(unsigned int pMapId, const std::string &basePath, uint32 tileX, uint32 tileY)
|
||||
{
|
||||
InstanceTreeMap::iterator instanceTree = iInstanceMapTrees.find(pMapId);
|
||||
if (instanceTree == iInstanceMapTrees.end())
|
||||
{
|
||||
std::string mapFileName = getMapFileName(pMapId);
|
||||
StaticMapTree *newTree = new StaticMapTree(pMapId, basePath);
|
||||
if (!newTree->InitMap(mapFileName, this))
|
||||
return false;
|
||||
instanceTree = iInstanceMapTrees.insert(InstanceTreeMap::value_type(pMapId, newTree)).first;
|
||||
}
|
||||
return instanceTree->second->LoadMapTile(tileX, tileY, this);
|
||||
}
|
||||
|
||||
//=========================================================
|
||||
|
||||
void VMapManager2::unloadMap(unsigned int pMapId)
|
||||
{
|
||||
InstanceTreeMap::iterator instanceTree = iInstanceMapTrees.find(pMapId);
|
||||
if (instanceTree != iInstanceMapTrees.end())
|
||||
{
|
||||
instanceTree->second->UnloadMap(this);
|
||||
if (instanceTree->second->numLoadedTiles() == 0)
|
||||
{
|
||||
delete instanceTree->second;
|
||||
iInstanceMapTrees.erase(pMapId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//=========================================================
|
||||
|
||||
void VMapManager2::unloadMap(unsigned int pMapId, int x, int y)
|
||||
{
|
||||
InstanceTreeMap::iterator instanceTree = iInstanceMapTrees.find(pMapId);
|
||||
if (instanceTree != iInstanceMapTrees.end())
|
||||
{
|
||||
instanceTree->second->UnloadMapTile(x, y, this);
|
||||
if (instanceTree->second->numLoadedTiles() == 0)
|
||||
{
|
||||
delete instanceTree->second;
|
||||
iInstanceMapTrees.erase(pMapId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//==========================================================
|
||||
|
||||
bool VMapManager2::isInLineOfSight(unsigned int pMapId, float x1, float y1, float z1, float x2, float y2, float z2)
|
||||
{
|
||||
if (!isLineOfSightCalcEnabled()) return true;
|
||||
bool result = true;
|
||||
InstanceTreeMap::iterator instanceTree = iInstanceMapTrees.find(pMapId);
|
||||
if (instanceTree != iInstanceMapTrees.end())
|
||||
{
|
||||
Vector3 pos1 = convertPositionToInternalRep(x1,y1,z1);
|
||||
Vector3 pos2 = convertPositionToInternalRep(x2,y2,z2);
|
||||
if (pos1 != pos2)
|
||||
{
|
||||
result = instanceTree->second->isInLineOfSight(pos1, pos2);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
//=========================================================
|
||||
/**
|
||||
get the hit position and return true if we hit something
|
||||
otherwise the result pos will be the dest pos
|
||||
*/
|
||||
bool VMapManager2::getObjectHitPos(unsigned int pMapId, float x1, float y1, float z1, float x2, float y2, float z2, float& rx, float &ry, float& rz, float pModifyDist)
|
||||
{
|
||||
bool result = false;
|
||||
rx=x2;
|
||||
ry=y2;
|
||||
rz=z2;
|
||||
if (isLineOfSightCalcEnabled())
|
||||
{
|
||||
InstanceTreeMap::iterator instanceTree = iInstanceMapTrees.find(pMapId);
|
||||
if (instanceTree != iInstanceMapTrees.end())
|
||||
{
|
||||
Vector3 pos1 = convertPositionToInternalRep(x1,y1,z1);
|
||||
Vector3 pos2 = convertPositionToInternalRep(x2,y2,z2);
|
||||
Vector3 resultPos;
|
||||
result = instanceTree->second->getObjectHitPos(pos1, pos2, resultPos, pModifyDist);
|
||||
resultPos = convertPositionToMangosRep(resultPos.x,resultPos.y,resultPos.z);
|
||||
rx = resultPos.x;
|
||||
ry = resultPos.y;
|
||||
rz = resultPos.z;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
//=========================================================
|
||||
/**
|
||||
get height or INVALID_HEIGHT if no height available
|
||||
*/
|
||||
|
||||
float VMapManager2::getHeight(unsigned int pMapId, float x, float y, float z)
|
||||
{
|
||||
float height = VMAP_INVALID_HEIGHT_VALUE; //no height
|
||||
if (isHeightCalcEnabled())
|
||||
{
|
||||
InstanceTreeMap::iterator instanceTree = iInstanceMapTrees.find(pMapId);
|
||||
if (instanceTree != iInstanceMapTrees.end())
|
||||
{
|
||||
Vector3 pos = convertPositionToInternalRep(x,y,z);
|
||||
height = instanceTree->second->getHeight(pos);
|
||||
if (!(height < G3D::inf()))
|
||||
{
|
||||
height = VMAP_INVALID_HEIGHT_VALUE; //no height
|
||||
}
|
||||
}
|
||||
}
|
||||
return height;
|
||||
}
|
||||
|
||||
//=========================================================
|
||||
|
||||
bool VMapManager2::getAreaInfo(unsigned int pMapId, float x, float y, float &z, uint32 &flags, int32 &adtId, int32 &rootId, int32 &groupId) const
|
||||
{
|
||||
bool result=false;
|
||||
InstanceTreeMap::const_iterator instanceTree = iInstanceMapTrees.find(pMapId);
|
||||
if (instanceTree != iInstanceMapTrees.end())
|
||||
{
|
||||
Vector3 pos = convertPositionToInternalRep(x, y, z);
|
||||
result = instanceTree->second->getAreaInfo(pos, flags, adtId, rootId, groupId);
|
||||
// z is not touched by convertPositionToMangosRep(), so just copy
|
||||
z = pos.z;
|
||||
}
|
||||
return(result);
|
||||
}
|
||||
|
||||
bool VMapManager2::GetLiquidLevel(uint32 pMapId, float x, float y, float z, uint8 ReqLiquidType, float &level, float &floor, uint32 &type) const
|
||||
{
|
||||
InstanceTreeMap::const_iterator instanceTree = iInstanceMapTrees.find(pMapId);
|
||||
if (instanceTree != iInstanceMapTrees.end())
|
||||
{
|
||||
LocationInfo info;
|
||||
Vector3 pos = convertPositionToInternalRep(x, y, z);
|
||||
if (instanceTree->second->GetLocationInfo(pos, info))
|
||||
{
|
||||
floor = info.ground_Z;
|
||||
type = info.hitModel->GetLiquidType();
|
||||
if (ReqLiquidType && !(type & ReqLiquidType))
|
||||
return false;
|
||||
if (info.hitInstance->GetLiquidLevel(pos, info, level))
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//=========================================================
|
||||
|
||||
WorldModel* VMapManager2::acquireModelInstance(const std::string &basepath, const std::string &filename)
|
||||
{
|
||||
ModelFileMap::iterator model = iLoadedModelFiles.find(filename);
|
||||
if (model == iLoadedModelFiles.end())
|
||||
{
|
||||
WorldModel *worldmodel = new WorldModel();
|
||||
if (!worldmodel->readFile(basepath + filename + ".vmo"))
|
||||
{
|
||||
std::cout << "VMapManager2: could not load '" << basepath << filename << ".vmo'!\n";
|
||||
delete worldmodel;
|
||||
return NULL;
|
||||
}
|
||||
std::cout << "VMapManager2: loading file '" << basepath << filename << "'.\n";
|
||||
model = iLoadedModelFiles.insert(std::pair<std::string, ManagedModel>(filename, ManagedModel())).first;
|
||||
model->second.setModel(worldmodel);
|
||||
}
|
||||
model->second.incRefCount();
|
||||
return model->second.getModel();
|
||||
}
|
||||
|
||||
void VMapManager2::releaseModelInstance(const std::string &filename)
|
||||
{
|
||||
ModelFileMap::iterator model = iLoadedModelFiles.find(filename);
|
||||
if (model == iLoadedModelFiles.end())
|
||||
{
|
||||
std::cout << "VMapManager2: trying to unload non-loaded file '" << filename << "'!\n";
|
||||
return;
|
||||
}
|
||||
if( model->second.decRefCount() == 0)
|
||||
{
|
||||
std::cout << "VMapManager2: unloading file '" << filename << "'.\n";
|
||||
delete model->second.getModel();
|
||||
iLoadedModelFiles.erase(model);
|
||||
}
|
||||
}
|
||||
//=========================================================
|
||||
|
||||
bool VMapManager2::existsMap(const char* pBasePath, unsigned int pMapId, int x, int y)
|
||||
{
|
||||
return StaticMapTree::CanLoadMap(std::string(pBasePath), pMapId, x, y);
|
||||
}
|
||||
|
||||
} // namespace VMAP
|
||||
@@ -0,0 +1,114 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2010 MaNGOS <http://getmangos.com/>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public 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 _VMAPMANAGER2_H
|
||||
#define _VMAPMANAGER2_H
|
||||
|
||||
#include "IVMapManager.h"
|
||||
#include "Utilities/UnorderedMap.h"
|
||||
#include "Platform/Define.h"
|
||||
#include <G3D/Vector3.h>
|
||||
|
||||
//===========================================================
|
||||
|
||||
#define MAP_FILENAME_EXTENSION2 ".vmtree"
|
||||
|
||||
#define FILENAMEBUFFER_SIZE 500
|
||||
|
||||
/**
|
||||
This is the main Class to manage loading and unloading of maps, line of sight, height calculation and so on.
|
||||
For each map or map tile to load it reads a directory file that contains the ModelContainer files used by this map or map tile.
|
||||
Each global map or instance has its own dynamic BSP-Tree.
|
||||
The loaded ModelContainers are included in one of these BSP-Trees.
|
||||
Additionally a table to match map ids and map names is used.
|
||||
*/
|
||||
|
||||
//===========================================================
|
||||
|
||||
namespace VMAP
|
||||
{
|
||||
class StaticMapTree;
|
||||
class WorldModel;
|
||||
|
||||
class ManagedModel
|
||||
{
|
||||
public:
|
||||
ManagedModel(): iModel(0), iRefCount(0) {}
|
||||
void setModel(WorldModel *model) { iModel = model; }
|
||||
WorldModel *getModel() { return iModel; }
|
||||
void incRefCount() { ++iRefCount; }
|
||||
int decRefCount() { return --iRefCount; }
|
||||
protected:
|
||||
WorldModel *iModel;
|
||||
int iRefCount;
|
||||
};
|
||||
|
||||
typedef UNORDERED_MAP<uint32 , StaticMapTree *> InstanceTreeMap;
|
||||
typedef UNORDERED_MAP<std::string, ManagedModel> ModelFileMap;
|
||||
|
||||
class VMapManager2 : public IVMapManager
|
||||
{
|
||||
protected:
|
||||
// Tree to check collision
|
||||
ModelFileMap iLoadedModelFiles;
|
||||
InstanceTreeMap iInstanceMapTrees;
|
||||
// UNORDERED_MAP<unsigned int , bool> iMapsSplitIntoTiles;
|
||||
UNORDERED_MAP<unsigned int , bool> iIgnoreMapIds;
|
||||
|
||||
bool _loadMap(uint32 pMapId, const std::string &basePath, uint32 tileX, uint32 tileY);
|
||||
/* void _unloadMap(uint32 pMapId, uint32 x, uint32 y); */
|
||||
|
||||
public:
|
||||
// public for debug
|
||||
G3D::Vector3 convertPositionToInternalRep(float x, float y, float z) const;
|
||||
G3D::Vector3 convertPositionToMangosRep(float x, float y, float z) const;
|
||||
static std::string getMapFileName(unsigned int pMapId);
|
||||
|
||||
VMapManager2();
|
||||
~VMapManager2(void);
|
||||
|
||||
int loadMap(const char* pBasePath, unsigned int pMapId, int x, int y);
|
||||
|
||||
void unloadMap(unsigned int pMapId, int x, int y);
|
||||
void unloadMap(unsigned int pMapId);
|
||||
|
||||
bool isInLineOfSight(unsigned int pMapId, float x1, float y1, float z1, float x2, float y2, float z2) ;
|
||||
/**
|
||||
fill the hit pos and return true, if an object was hit
|
||||
*/
|
||||
bool getObjectHitPos(unsigned int pMapId, float x1, float y1, float z1, float x2, float y2, float z2, float& rx, float &ry, float& rz, float pModifyDist);
|
||||
float getHeight(unsigned int pMapId, float x, float y, float z);
|
||||
|
||||
bool processCommand(char *pCommand) { return false; } // for debug and extensions
|
||||
|
||||
void preventMapsFromBeingUsed(const char* pMapIdString);
|
||||
bool getAreaInfo(unsigned int pMapId, float x, float y, float &z, uint32 &flags, int32 &adtId, int32 &rootId, int32 &groupId) const;
|
||||
bool GetLiquidLevel(uint32 pMapId, float x, float y, float z, uint8 ReqLiquidType, float &level, float &floor, uint32 &type) const;
|
||||
|
||||
WorldModel* acquireModelInstance(const std::string &basepath, const std::string &filename);
|
||||
void releaseModelInstance(const std::string &filename);
|
||||
|
||||
// what's the use of this? o.O
|
||||
virtual std::string getDirFileName(unsigned int pMapId, int x, int y) const
|
||||
{
|
||||
return getMapFileName(pMapId);
|
||||
}
|
||||
virtual bool existsMap(const char* pBasePath, unsigned int pMapId, int x, int y);
|
||||
};
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,150 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2010 MaNGOS <http://getmangos.com/>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public 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 _VMAPTOOLS_H
|
||||
#define _VMAPTOOLS_H
|
||||
|
||||
#include <G3D/CollisionDetection.h>
|
||||
#include <G3D/AABox.h>
|
||||
|
||||
#include "NodeValueAccess.h"
|
||||
|
||||
/**
|
||||
The Class is mainly taken from G3D/AABSPTree.h but modified to be able to use our internal data structure.
|
||||
This is an iterator that helps us analysing the BSP-Trees.
|
||||
The collision detection is modified to return true, if we are inside an object.
|
||||
*/
|
||||
|
||||
namespace VMAP
|
||||
{
|
||||
template<class TValue>
|
||||
class IntersectionCallBack {
|
||||
public:
|
||||
TValue* closestEntity;
|
||||
G3D::Vector3 hitLocation;
|
||||
G3D::Vector3 hitNormal;
|
||||
|
||||
void operator()(const G3D::Ray& ray, const TValue* entity, bool pStopAtFirstHit, float& distance) {
|
||||
entity->intersect(ray, distance, pStopAtFirstHit, hitLocation, hitNormal);
|
||||
}
|
||||
};
|
||||
|
||||
//==============================================================
|
||||
//==============================================================
|
||||
//==============================================================
|
||||
|
||||
class MyCollisionDetection
|
||||
{
|
||||
private:
|
||||
public:
|
||||
|
||||
static bool collisionLocationForMovingPointFixedAABox(
|
||||
const G3D::Vector3& origin,
|
||||
const G3D::Vector3& dir,
|
||||
const G3D::AABox& box,
|
||||
G3D::Vector3& location,
|
||||
bool& Inside)
|
||||
{
|
||||
|
||||
// Integer representation of a floating-point value.
|
||||
#define IR(x) (reinterpret_cast<G3D::uint32 const&>(x))
|
||||
|
||||
Inside = true;
|
||||
const G3D::Vector3& MinB = box.low();
|
||||
const G3D::Vector3& MaxB = box.high();
|
||||
G3D::Vector3 MaxT(-1.0f, -1.0f, -1.0f);
|
||||
|
||||
// Find candidate planes.
|
||||
for (int i = 0; i < 3; ++i)
|
||||
{
|
||||
if (origin[i] < MinB[i])
|
||||
{
|
||||
location[i] = MinB[i];
|
||||
Inside = false;
|
||||
|
||||
// Calculate T distances to candidate planes
|
||||
if (IR(dir[i]))
|
||||
{
|
||||
MaxT[i] = (MinB[i] - origin[i]) / dir[i];
|
||||
}
|
||||
}
|
||||
else if (origin[i] > MaxB[i])
|
||||
{
|
||||
location[i] = MaxB[i];
|
||||
Inside = false;
|
||||
|
||||
// Calculate T distances to candidate planes
|
||||
if (IR(dir[i]))
|
||||
{
|
||||
MaxT[i] = (MaxB[i] - origin[i]) / dir[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (Inside)
|
||||
{
|
||||
// definite hit
|
||||
location = origin;
|
||||
return true;
|
||||
}
|
||||
|
||||
// Get largest of the maxT's for final choice of intersection
|
||||
int WhichPlane = 0;
|
||||
if (MaxT[1] > MaxT[WhichPlane])
|
||||
{
|
||||
WhichPlane = 1;
|
||||
}
|
||||
|
||||
if (MaxT[2] > MaxT[WhichPlane])
|
||||
{
|
||||
WhichPlane = 2;
|
||||
}
|
||||
|
||||
// Check final candidate actually inside box
|
||||
if (IR(MaxT[WhichPlane]) & 0x80000000)
|
||||
{
|
||||
// Miss the box
|
||||
return false;
|
||||
}
|
||||
|
||||
for (int i = 0; i < 3; ++i)
|
||||
{
|
||||
if (i != WhichPlane)
|
||||
{
|
||||
location[i] = origin[i] + MaxT[WhichPlane] * dir[i];
|
||||
if ((location[i] < MinB[i]) ||
|
||||
(location[i] > MaxB[i]))
|
||||
{
|
||||
// On this plane we're outside the box extents, so
|
||||
// we miss the box
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
/*
|
||||
// Choose the normal to be the plane normal facing into the ray
|
||||
normal = G3D::Vector3::zero();
|
||||
normal[WhichPlane] = (dir[WhichPlane] > 0) ? -1.0 : 1.0;
|
||||
*/
|
||||
return true;
|
||||
|
||||
#undef IR
|
||||
}
|
||||
};
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,535 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2010 MaNGOS <http://getmangos.com/>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public 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 "WorldModel.h"
|
||||
#include "VMapDefinitions.h"
|
||||
#include "MapTree.h"
|
||||
|
||||
using G3D::Vector3;
|
||||
using G3D::Ray;
|
||||
|
||||
template<> struct BoundsTrait<VMAP::GroupModel>
|
||||
{
|
||||
static void getBounds(const VMAP::GroupModel& obj, G3D::AABox& out) { out = obj.GetBound(); }
|
||||
};
|
||||
|
||||
|
||||
namespace VMAP
|
||||
{
|
||||
bool IntersectTriangle(const MeshTriangle &tri, std::vector<Vector3>::const_iterator points, const G3D::Ray &ray, float &distance)
|
||||
{
|
||||
static const float EPS = 1e-5f;
|
||||
|
||||
// See RTR2 ch. 13.7 for the algorithm.
|
||||
|
||||
const Vector3 e1 = points[tri.idx1] - points[tri.idx0];
|
||||
const Vector3 e2 = points[tri.idx2] - points[tri.idx0];
|
||||
const Vector3 p(ray.direction().cross(e2));
|
||||
const float a = e1.dot(p);
|
||||
|
||||
if (abs(a) < EPS) {
|
||||
// Determinant is ill-conditioned; abort early
|
||||
return false;
|
||||
}
|
||||
|
||||
const float f = 1.0f / a;
|
||||
const Vector3 s(ray.origin() - points[tri.idx0]);
|
||||
const float u = f * s.dot(p);
|
||||
|
||||
if ((u < 0.0f) || (u > 1.0f)) {
|
||||
// We hit the plane of the m_geometry, but outside the m_geometry
|
||||
return false;
|
||||
}
|
||||
|
||||
const Vector3 q(s.cross(e1));
|
||||
const float v = f * ray.direction().dot(q);
|
||||
|
||||
if ((v < 0.0f) || ((u + v) > 1.0f)) {
|
||||
// We hit the plane of the triangle, but outside the triangle
|
||||
return false;
|
||||
}
|
||||
|
||||
const float t = f * e2.dot(q);
|
||||
|
||||
if ((t > 0.0f) && (t < distance))
|
||||
{
|
||||
// This is a new hit, closer than the previous one
|
||||
distance = t;
|
||||
|
||||
/* baryCoord[0] = 1.0 - u - v;
|
||||
baryCoord[1] = u;
|
||||
baryCoord[2] = v; */
|
||||
|
||||
return true;
|
||||
}
|
||||
// This hit is after the previous hit, so ignore it
|
||||
return false;
|
||||
}
|
||||
|
||||
class TriBoundFunc
|
||||
{
|
||||
public:
|
||||
TriBoundFunc(std::vector<Vector3> &vert): vertices(vert.begin()) {}
|
||||
void operator()(const MeshTriangle &tri, G3D::AABox &out) const
|
||||
{
|
||||
G3D::Vector3 lo = vertices[tri.idx0];
|
||||
G3D::Vector3 hi = lo;
|
||||
|
||||
lo = (lo.min(vertices[tri.idx1])).min(vertices[tri.idx2]);
|
||||
hi = (hi.max(vertices[tri.idx1])).max(vertices[tri.idx2]);
|
||||
|
||||
out = G3D::AABox(lo, hi);
|
||||
}
|
||||
protected:
|
||||
const std::vector<Vector3>::const_iterator vertices;
|
||||
};
|
||||
|
||||
// ===================== WmoLiquid ==================================
|
||||
|
||||
WmoLiquid::WmoLiquid(uint32 width, uint32 height, const Vector3 &corner, uint32 type):
|
||||
iTilesX(width), iTilesY(height), iCorner(corner), iType(type)
|
||||
{
|
||||
iHeight = new float[(width+1)*(height+1)];
|
||||
iFlags = new uint8[width*height];
|
||||
}
|
||||
|
||||
WmoLiquid::WmoLiquid(const WmoLiquid &other): iHeight(0), iFlags(0)
|
||||
{
|
||||
*this = other; // use assignment operator...
|
||||
}
|
||||
|
||||
WmoLiquid::~WmoLiquid()
|
||||
{
|
||||
delete[] iHeight;
|
||||
delete[] iFlags;
|
||||
}
|
||||
|
||||
WmoLiquid& WmoLiquid::operator=(const WmoLiquid &other)
|
||||
{
|
||||
if (this == &other)
|
||||
return *this;
|
||||
iTilesX = other.iTilesX;
|
||||
iTilesY = other.iTilesY;
|
||||
iCorner = other.iCorner;
|
||||
iType = other.iType;
|
||||
delete iHeight;
|
||||
delete iFlags;
|
||||
if (other.iHeight)
|
||||
{
|
||||
iHeight = new float[(iTilesX+1)*(iTilesY+1)];
|
||||
memcpy(iHeight, other.iHeight, (iTilesX+1)*(iTilesY+1)*sizeof(float));
|
||||
}
|
||||
else
|
||||
iHeight = 0;
|
||||
if (other.iFlags)
|
||||
{
|
||||
iFlags = new uint8[iTilesX * iTilesY];
|
||||
memcpy(iFlags, other.iFlags, iTilesX * iTilesY);
|
||||
}
|
||||
else
|
||||
iFlags = 0;
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool WmoLiquid::GetLiquidHeight(const Vector3 &pos, float &liqHeight) const
|
||||
{
|
||||
uint32 tx = (pos.x - iCorner.x)/LIQUID_TILE_SIZE;
|
||||
if (tx<0 || tx >= iTilesX) return false;
|
||||
uint32 ty = (pos.y - iCorner.y)/LIQUID_TILE_SIZE;
|
||||
if (ty<0 || ty >= iTilesY) return false;
|
||||
// checking for 0x08 *might* be enough, but disabled tiles always are 0x?F:
|
||||
if ((iFlags[tx + ty*iTilesX] & 0x0F) == 0x0F)
|
||||
return false;
|
||||
//placeholder...use only lower left corner vertex
|
||||
liqHeight = /* iCorner.z + */ iHeight[tx + ty*(iTilesX+1)];
|
||||
return true;
|
||||
}
|
||||
|
||||
uint32 WmoLiquid::GetFileSize()
|
||||
{
|
||||
return 2 * sizeof(uint32) +
|
||||
sizeof(Vector3) +
|
||||
(iTilesX + 1)*(iTilesY + 1) * sizeof(float) +
|
||||
iTilesX * iTilesY;
|
||||
}
|
||||
|
||||
bool WmoLiquid::writeToFile(FILE *wf)
|
||||
{
|
||||
bool result = true;
|
||||
if (result && fwrite(&iTilesX, sizeof(uint32), 1, wf) != 1) result = false;
|
||||
if (result && fwrite(&iTilesY, sizeof(uint32), 1, wf) != 1) result = false;
|
||||
if (result && fwrite(&iCorner, sizeof(Vector3), 1, wf) != 1) result = false;
|
||||
if (result && fwrite(&iType, sizeof(uint32), 1, wf) != 1) result = false;
|
||||
uint32 size = (iTilesX + 1)*(iTilesY + 1);
|
||||
if (result && fwrite(iHeight, sizeof(float), size, wf) != size) result = false;
|
||||
size = iTilesX*iTilesY;
|
||||
if (result && fwrite(iFlags, sizeof(uint8), size, wf) != size) result = false;
|
||||
return result;
|
||||
}
|
||||
|
||||
bool WmoLiquid::readFromFile(FILE *rf, WmoLiquid *&out)
|
||||
{
|
||||
bool result = true;
|
||||
WmoLiquid *liquid = new WmoLiquid();
|
||||
if (result && fread(&liquid->iTilesX, sizeof(uint32), 1, rf) != 1) result = false;
|
||||
if (result && fread(&liquid->iTilesY, sizeof(uint32), 1, rf) != 1) result = false;
|
||||
if (result && fread(&liquid->iCorner, sizeof(Vector3), 1, rf) != 1) result = false;
|
||||
if (result && fread(&liquid->iType, sizeof(uint32), 1, rf) != 1) result = false;
|
||||
uint32 size = (liquid->iTilesX + 1)*(liquid->iTilesY + 1);
|
||||
liquid->iHeight = new float[size];
|
||||
if (result && fread(liquid->iHeight, sizeof(float), size, rf) != size) result = false;
|
||||
size = liquid->iTilesX * liquid->iTilesY;
|
||||
liquid->iFlags = new uint8[size];
|
||||
if (result && fread(liquid->iFlags, sizeof(uint8), size, rf) != size) result = false;
|
||||
if (!result)
|
||||
delete liquid;
|
||||
out = liquid;
|
||||
return result;
|
||||
}
|
||||
|
||||
// ===================== GroupModel ==================================
|
||||
|
||||
GroupModel::GroupModel(const GroupModel &other):
|
||||
iBound(other.iBound), iMogpFlags(other.iMogpFlags), iGroupWMOID(other.iGroupWMOID),
|
||||
vertices(other.vertices), triangles(other.triangles), meshTree(other.meshTree), iLiquid(0)
|
||||
{
|
||||
if (other.iLiquid)
|
||||
iLiquid = new WmoLiquid(*other.iLiquid);
|
||||
}
|
||||
|
||||
void GroupModel::setMeshData(std::vector<Vector3> &vert, std::vector<MeshTriangle> &tri)
|
||||
{
|
||||
vertices.swap(vert);
|
||||
triangles.swap(tri);
|
||||
TriBoundFunc bFunc(vertices);
|
||||
meshTree.build(triangles, bFunc);
|
||||
}
|
||||
|
||||
bool GroupModel::writeToFile(FILE *wf)
|
||||
{
|
||||
bool result = true;
|
||||
uint32 chunkSize, count;
|
||||
|
||||
if (result && fwrite(&iBound, sizeof(G3D::AABox), 1, wf) != 1) result = false;
|
||||
if (result && fwrite(&iMogpFlags, sizeof(uint32), 1, wf) != 1) result = false;
|
||||
if (result && fwrite(&iGroupWMOID, sizeof(uint32), 1, wf) != 1) result = false;
|
||||
|
||||
// write vertices
|
||||
if (result && fwrite("VERT", 1, 4, wf) != 4) result = false;
|
||||
count = vertices.size();
|
||||
chunkSize = sizeof(uint32)+ sizeof(Vector3)*count;
|
||||
if (result && fwrite(&chunkSize, sizeof(uint32), 1, wf) != 1) result = false;
|
||||
if (result && fwrite(&count, sizeof(uint32), 1, wf) != 1) result = false;
|
||||
if (!count) // models without (collision) geometry end here, unsure if they are useful
|
||||
return result;
|
||||
if (result && fwrite(&vertices[0], sizeof(Vector3), count, wf) != count) result = false;
|
||||
|
||||
// write triangle mesh
|
||||
if (result && fwrite("TRIM", 1, 4, wf) != 4) result = false;
|
||||
count = triangles.size();
|
||||
chunkSize = sizeof(uint32)+ sizeof(MeshTriangle)*count;
|
||||
if (result && fwrite(&chunkSize, sizeof(uint32), 1, wf) != 1) result = false;
|
||||
if (result && fwrite(&count, sizeof(uint32), 1, wf) != 1) result = false;
|
||||
if (result && fwrite(&triangles[0], sizeof(MeshTriangle), count, wf) != count) result = false;
|
||||
|
||||
// write mesh BIH
|
||||
if (result && fwrite("MBIH", 1, 4, wf) != 4) result = false;
|
||||
if (result) result = meshTree.writeToFile(wf);
|
||||
|
||||
// write liquid data
|
||||
if (result && fwrite("LIQU", 1, 4, wf) != 4) result = false;
|
||||
if (!iLiquid)
|
||||
{
|
||||
chunkSize = 0;
|
||||
if (result && fwrite(&chunkSize, sizeof(uint32), 1, wf) != 1) result = false;
|
||||
return result;
|
||||
}
|
||||
chunkSize = iLiquid->GetFileSize();
|
||||
if (result && fwrite(&chunkSize, sizeof(uint32), 1, wf) != 1) result = false;
|
||||
if (result) result = iLiquid->writeToFile(wf);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
bool GroupModel::readFromFile(FILE *rf)
|
||||
{
|
||||
char chunk[8];
|
||||
bool result = true;
|
||||
uint32 chunkSize, count;
|
||||
triangles.clear();
|
||||
vertices.clear();
|
||||
delete iLiquid;
|
||||
iLiquid = 0;
|
||||
|
||||
if (result && fread(&iBound, sizeof(G3D::AABox), 1, rf) != 1) result = false;
|
||||
if (result && fread(&iMogpFlags, sizeof(uint32), 1, rf) != 1) result = false;
|
||||
if (result && fread(&iGroupWMOID, sizeof(uint32), 1, rf) != 1) result = false;
|
||||
|
||||
// read vertices
|
||||
if (result && !readChunk(rf, chunk, "VERT", 4)) result = false;
|
||||
if (result && fread(&chunkSize, sizeof(uint32), 1, rf) != 1) result = false;
|
||||
if (result && fread(&count, sizeof(uint32), 1, rf) != 1) result = false;
|
||||
if (!count) // models without (collision) geometry end here, unsure if they are useful
|
||||
return result;
|
||||
if (result) vertices.resize(count);
|
||||
if (result && fread(&vertices[0], sizeof(Vector3), count, rf) != count) result = false;
|
||||
|
||||
// read triangle mesh
|
||||
if (result && !readChunk(rf, chunk, "TRIM", 4)) result = false;
|
||||
if (result && fread(&chunkSize, sizeof(uint32), 1, rf) != 1) result = false;
|
||||
if (result && fread(&count, sizeof(uint32), 1, rf) != 1) result = false;
|
||||
if (result) triangles.resize(count);
|
||||
if (result && fread(&triangles[0], sizeof(MeshTriangle), count, rf) != count) result = false;
|
||||
|
||||
// read mesh BIH
|
||||
if (result && !readChunk(rf, chunk, "MBIH", 4)) result = false;
|
||||
if (result) result = meshTree.readFromFile(rf);
|
||||
|
||||
// write liquid data
|
||||
if (result && !readChunk(rf, chunk, "LIQU", 4)) result = false;
|
||||
if (result && fread(&chunkSize, sizeof(uint32), 1, rf) != 1) result = false;
|
||||
if (result && chunkSize > 0)
|
||||
result = WmoLiquid::readFromFile(rf, iLiquid);
|
||||
return result;
|
||||
}
|
||||
|
||||
struct GModelRayCallback
|
||||
{
|
||||
GModelRayCallback(const std::vector<MeshTriangle> &tris, const std::vector<Vector3> &vert):
|
||||
vertices(vert.begin()), triangles(tris.begin()), hit(false) {}
|
||||
bool operator()(const G3D::Ray& ray, uint32 entry, float& distance, bool pStopAtFirstHit)
|
||||
{
|
||||
bool result = IntersectTriangle(triangles[entry], vertices, ray, distance);
|
||||
if (result) hit=true;
|
||||
return hit;
|
||||
}
|
||||
std::vector<Vector3>::const_iterator vertices;
|
||||
std::vector<MeshTriangle>::const_iterator triangles;
|
||||
bool hit;
|
||||
};
|
||||
|
||||
bool GroupModel::IntersectRay(const G3D::Ray &ray, float &distance, bool stopAtFirstHit) const
|
||||
{
|
||||
if (!triangles.size())
|
||||
return false;
|
||||
GModelRayCallback callback(triangles, vertices);
|
||||
meshTree.intersectRay(ray, callback, distance, stopAtFirstHit);
|
||||
return callback.hit;
|
||||
}
|
||||
|
||||
bool GroupModel::IsInsideObject(const Vector3 &pos, const Vector3 &down, float &z_dist) const
|
||||
{
|
||||
if (!triangles.size() || !iBound.contains(pos))
|
||||
return false;
|
||||
GModelRayCallback callback(triangles, vertices);
|
||||
Vector3 rPos = pos - 0.1f * down;
|
||||
float dist = G3D::inf();
|
||||
G3D::Ray ray(rPos, down);
|
||||
bool hit = IntersectRay(ray, dist, false);
|
||||
if (hit)
|
||||
z_dist = dist - 0.1f;
|
||||
return hit;
|
||||
}
|
||||
|
||||
bool GroupModel::GetLiquidLevel(const Vector3 &pos, float &liqHeight) const
|
||||
{
|
||||
if (iLiquid)
|
||||
return iLiquid->GetLiquidHeight(pos, liqHeight);
|
||||
return false;
|
||||
}
|
||||
|
||||
uint32 GroupModel::GetLiquidType() const
|
||||
{
|
||||
// convert to type mask, matching MAP_LIQUID_TYPE_* defines in Map.h
|
||||
if (iLiquid)
|
||||
return (1 << iLiquid->GetType());
|
||||
return 0;
|
||||
}
|
||||
|
||||
// ===================== WorldModel ==================================
|
||||
|
||||
void WorldModel::setGroupModels(std::vector<GroupModel> &models)
|
||||
{
|
||||
groupModels.swap(models);
|
||||
groupTree.build(groupModels, BoundsTrait<GroupModel>::getBounds, 1);
|
||||
}
|
||||
|
||||
struct WModelRayCallBack
|
||||
{
|
||||
WModelRayCallBack(const std::vector<GroupModel> &mod): models(mod.begin()), hit(false) {}
|
||||
bool operator()(const G3D::Ray& ray, uint32 entry, float& distance, bool pStopAtFirstHit)
|
||||
{
|
||||
bool result = models[entry].IntersectRay(ray, distance, pStopAtFirstHit);
|
||||
if (result) hit=true;
|
||||
return hit;
|
||||
}
|
||||
std::vector<GroupModel>::const_iterator models;
|
||||
bool hit;
|
||||
};
|
||||
|
||||
bool WorldModel::IntersectRay(const G3D::Ray &ray, float &distance, bool stopAtFirstHit) const
|
||||
{
|
||||
// small M2 workaround, maybe better make separate class with virtual intersection funcs
|
||||
// in any case, there's no need to use a bound tree if we only have one submodel
|
||||
if (groupModels.size() == 1)
|
||||
return groupModels[0].IntersectRay(ray, distance, stopAtFirstHit);
|
||||
|
||||
WModelRayCallBack isc(groupModels);
|
||||
groupTree.intersectRay(ray, isc, distance, stopAtFirstHit);
|
||||
return isc.hit;
|
||||
}
|
||||
|
||||
class WModelAreaCallback {
|
||||
public:
|
||||
WModelAreaCallback(const std::vector<GroupModel> &vals, const Vector3 &down):
|
||||
prims(vals.begin()), hit(vals.end()), minVol(G3D::inf()), zDist(G3D::inf()), zVec(down) {}
|
||||
std::vector<GroupModel>::const_iterator prims;
|
||||
std::vector<GroupModel>::const_iterator hit;
|
||||
float minVol;
|
||||
float zDist;
|
||||
Vector3 zVec;
|
||||
void operator()(const Vector3& point, uint32 entry)
|
||||
{
|
||||
float group_Z;
|
||||
//float pVol = prims[entry].GetBound().volume();
|
||||
//if(pVol < minVol)
|
||||
//{
|
||||
/* if (prims[entry].iBound.contains(point)) */
|
||||
if (prims[entry].IsInsideObject(point, zVec, group_Z))
|
||||
{
|
||||
//minVol = pVol;
|
||||
//hit = prims + entry;
|
||||
if (group_Z < zDist)
|
||||
{
|
||||
zDist = group_Z;
|
||||
hit = prims + entry;
|
||||
}
|
||||
#ifdef VMAP_DEBUG
|
||||
const GroupModel &gm = prims[entry];
|
||||
printf("%10u %8X %7.3f,%7.3f,%7.3f | %7.3f,%7.3f,%7.3f | z=%f, p_z=%f\n", gm.GetWmoID(), gm.GetMogpFlags(),
|
||||
gm.GetBound().low().x, gm.GetBound().low().y, gm.GetBound().low().z,
|
||||
gm.GetBound().high().x, gm.GetBound().high().y, gm.GetBound().high().z, group_Z, point.z);
|
||||
#endif
|
||||
}
|
||||
//}
|
||||
//std::cout << "trying to intersect '" << prims[entry].name << "'\n";
|
||||
}
|
||||
};
|
||||
|
||||
bool WorldModel::IntersectPoint(const G3D::Vector3 &p, const G3D::Vector3 &down, float &dist, AreaInfo &info) const
|
||||
{
|
||||
if (!groupModels.size())
|
||||
return false;
|
||||
WModelAreaCallback callback(groupModels, down);
|
||||
groupTree.intersectPoint(p, callback);
|
||||
if (callback.hit != groupModels.end())
|
||||
{
|
||||
info.rootId = RootWMOID;
|
||||
info.groupId = callback.hit->GetWmoID();
|
||||
info.flags = callback.hit->GetMogpFlags();
|
||||
info.result = true;
|
||||
dist = callback.zDist;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool WorldModel::GetLocationInfo(const G3D::Vector3 &p, const G3D::Vector3 &down, float &dist, LocationInfo &info) const
|
||||
{
|
||||
if (!groupModels.size())
|
||||
return false;
|
||||
WModelAreaCallback callback(groupModels, down);
|
||||
groupTree.intersectPoint(p, callback);
|
||||
if (callback.hit != groupModels.end())
|
||||
{
|
||||
info.hitModel = &(*callback.hit);
|
||||
dist = callback.zDist;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool WorldModel::writeFile(const std::string &filename)
|
||||
{
|
||||
FILE *wf = fopen(filename.c_str(), "wb");
|
||||
if (!wf)
|
||||
return false;
|
||||
|
||||
bool result = true;
|
||||
uint32 chunkSize, count;
|
||||
result = fwrite(VMAP_MAGIC,1,8,wf) == 8;
|
||||
if (result && fwrite("WMOD", 1, 4, wf) != 4) result = false;
|
||||
chunkSize = sizeof(uint32) + sizeof(uint32);
|
||||
if (result && fwrite(&chunkSize, sizeof(uint32), 1, wf) != 1) result = false;
|
||||
if (result && fwrite(&RootWMOID, sizeof(uint32), 1, wf) != 1) result = false;
|
||||
|
||||
// write group models
|
||||
count=groupModels.size();
|
||||
if (count)
|
||||
{
|
||||
if (result && fwrite("GMOD", 1, 4, wf) != 4) result = false;
|
||||
//chunkSize = sizeof(uint32)+ sizeof(GroupModel)*count;
|
||||
//if (result && fwrite(&chunkSize, sizeof(uint32), 1, wf) != 1) result = false;
|
||||
if (result && fwrite(&count, sizeof(uint32), 1, wf) != 1) result = false;
|
||||
for (uint32 i=0; i<groupModels.size() && result; ++i)
|
||||
result = groupModels[i].writeToFile(wf);
|
||||
|
||||
// write group BIH
|
||||
if (result && fwrite("GBIH", 1, 4, wf) != 4) result = false;
|
||||
if (result) result = groupTree.writeToFile(wf);
|
||||
}
|
||||
|
||||
fclose(wf);
|
||||
return result;
|
||||
}
|
||||
|
||||
bool WorldModel::readFile(const std::string &filename)
|
||||
{
|
||||
FILE *rf = fopen(filename.c_str(), "rb");
|
||||
if (!rf)
|
||||
return false;
|
||||
|
||||
bool result = true;
|
||||
uint32 chunkSize, count;
|
||||
char chunk[8]; // Ignore the added magic header
|
||||
if (!readChunk(rf, chunk, VMAP_MAGIC, 8)) result = false;
|
||||
|
||||
if (result && !readChunk(rf, chunk, "WMOD", 4)) result = false;
|
||||
if (result && fread(&chunkSize, sizeof(uint32), 1, rf) != 1) result = false;
|
||||
if (result && fread(&RootWMOID, sizeof(uint32), 1, rf) != 1) result = false;
|
||||
|
||||
// read group models
|
||||
if (result && readChunk(rf, chunk, "GMOD", 4))
|
||||
{
|
||||
//if (fread(&chunkSize, sizeof(uint32), 1, rf) != 1) result = false;
|
||||
|
||||
if (result && fread(&count, sizeof(uint32), 1, rf) != 1) result = false;
|
||||
if (result) groupModels.resize(count);
|
||||
//if (result && fread(&groupModels[0], sizeof(GroupModel), count, rf) != count) result = false;
|
||||
for (uint32 i=0; i<count && result; ++i)
|
||||
result = groupModels[i].readFromFile(rf);
|
||||
|
||||
// read group BIH
|
||||
if (result && !readChunk(rf, chunk, "GBIH", 4)) result = false;
|
||||
if (result) result = groupTree.readFromFile(rf);
|
||||
}
|
||||
|
||||
fclose(rf);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,123 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2010 MaNGOS <http://getmangos.com/>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public 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 _WORLDMODEL_H
|
||||
#define _WORLDMODEL_H
|
||||
|
||||
#include <G3D/HashTrait.h>
|
||||
#include <G3D/Vector3.h>
|
||||
#include <G3D/AABox.h>
|
||||
#include <G3D/Ray.h>
|
||||
#include "BIH.h"
|
||||
|
||||
#include "Platform/Define.h"
|
||||
|
||||
namespace VMAP
|
||||
{
|
||||
class TreeNode;
|
||||
struct AreaInfo;
|
||||
struct LocationInfo;
|
||||
|
||||
class MeshTriangle
|
||||
{
|
||||
public:
|
||||
MeshTriangle(){};
|
||||
MeshTriangle(uint32 na, uint32 nb, uint32 nc): idx0(na), idx1(nb), idx2(nc) {};
|
||||
|
||||
uint32 idx0;
|
||||
uint32 idx1;
|
||||
uint32 idx2;
|
||||
};
|
||||
|
||||
class WmoLiquid
|
||||
{
|
||||
public:
|
||||
WmoLiquid(uint32 width, uint32 height, const Vector3 &corner, uint32 type);
|
||||
WmoLiquid(const WmoLiquid &other);
|
||||
~WmoLiquid();
|
||||
WmoLiquid& operator=(const WmoLiquid &other);
|
||||
bool GetLiquidHeight(const Vector3 &pos, float &liqHeight) const;
|
||||
uint32 GetType() const { return iType; }
|
||||
float *GetHeightStorage() { return iHeight; }
|
||||
uint8 *GetFlagsStorage() { return iFlags; }
|
||||
uint32 GetFileSize();
|
||||
bool writeToFile(FILE *wf);
|
||||
static bool readFromFile(FILE *rf, WmoLiquid *&liquid);
|
||||
private:
|
||||
WmoLiquid(): iHeight(0), iFlags(0) {};
|
||||
uint32 iTilesX; //!< number of tiles in x direction, each
|
||||
uint32 iTilesY;
|
||||
Vector3 iCorner; //!< the lower corner
|
||||
uint32 iType; //!< liquid type
|
||||
float *iHeight; //!< (tilesX + 1)*(tilesY + 1) height values
|
||||
uint8 *iFlags; //!< info if liquid tile is used
|
||||
};
|
||||
|
||||
/*! holding additional info for WMO group files */
|
||||
class GroupModel
|
||||
{
|
||||
public:
|
||||
GroupModel(): iLiquid(0) {}
|
||||
GroupModel(const GroupModel &other);
|
||||
GroupModel(uint32 mogpFlags, uint32 groupWMOID, const AABox &bound):
|
||||
iBound(bound), iMogpFlags(mogpFlags), iGroupWMOID(groupWMOID), iLiquid(0) {}
|
||||
~GroupModel() { delete iLiquid; }
|
||||
|
||||
//! pass mesh data to object and create BIH. Passed vectors get get swapped with old geometry!
|
||||
void setMeshData(std::vector<Vector3> &vert, std::vector<MeshTriangle> &tri);
|
||||
void setLiquidData(WmoLiquid *liquid) { iLiquid = liquid; }
|
||||
bool IntersectRay(const G3D::Ray &ray, float &distance, bool stopAtFirstHit) const;
|
||||
bool IsInsideObject(const Vector3 &pos, const Vector3 &down, float &z_dist) const;
|
||||
bool GetLiquidLevel(const Vector3 &pos, float &liqHeight) const;
|
||||
uint32 GetLiquidType() const;
|
||||
bool writeToFile(FILE *wf);
|
||||
bool readFromFile(FILE *rf);
|
||||
const G3D::AABox& GetBound() const { return iBound; }
|
||||
uint32 GetMogpFlags() const { return iMogpFlags; }
|
||||
uint32 GetWmoID() const { return iGroupWMOID; }
|
||||
protected:
|
||||
G3D::AABox iBound;
|
||||
uint32 iMogpFlags;// 0x8 outdor; 0x2000 indoor
|
||||
uint32 iGroupWMOID;
|
||||
std::vector<Vector3> vertices;
|
||||
std::vector<MeshTriangle> triangles;
|
||||
BIH meshTree;
|
||||
WmoLiquid *iLiquid;
|
||||
};
|
||||
/*! Holds a model (converted M2 or WMO) in its original coordinate space */
|
||||
class WorldModel
|
||||
{
|
||||
public:
|
||||
WorldModel(): RootWMOID(0) {}
|
||||
|
||||
//! pass group models to WorldModel and create BIH. Passed vector is swapped with old geometry!
|
||||
void setGroupModels(std::vector<GroupModel> &models);
|
||||
void setRootWmoID(uint32 id) { RootWMOID = id; }
|
||||
bool IntersectRay(const G3D::Ray &ray, float &distance, bool stopAtFirstHit) const;
|
||||
bool IntersectPoint(const G3D::Vector3 &p, const G3D::Vector3 &down, float &dist, AreaInfo &info) const;
|
||||
bool GetLocationInfo(const G3D::Vector3 &p, const G3D::Vector3 &down, float &dist, LocationInfo &info) const;
|
||||
bool writeFile(const std::string &filename);
|
||||
bool readFile(const std::string &filename);
|
||||
protected:
|
||||
uint32 RootWMOID;
|
||||
std::vector<GroupModel> groupModels;
|
||||
BIH groupTree;
|
||||
};
|
||||
} // namespace VMAP
|
||||
|
||||
#endif // _WORLDMODEL_H
|
||||
Reference in New Issue
Block a user