aboutsummaryrefslogtreecommitdiff
path: root/src/server
diff options
context:
space:
mode:
Diffstat (limited to 'src/server')
-rw-r--r--src/server/CMakeLists.txt30
-rw-r--r--src/server/authserver/CMakeLists.txt23
-rw-r--r--src/server/collision/BoundingIntervalHierarchy.cpp310
-rw-r--r--src/server/collision/BoundingIntervalHierarchy.h400
-rw-r--r--src/server/collision/BoundingIntervalHierarchyWrapper.h119
-rw-r--r--src/server/collision/CMakeLists.txt97
-rw-r--r--src/server/collision/DynamicTree.cpp260
-rw-r--r--src/server/collision/DynamicTree.h64
-rw-r--r--src/server/collision/Management/IVMapManager.h100
-rw-r--r--src/server/collision/Management/MMapFactory.cpp44
-rw-r--r--src/server/collision/Management/MMapFactory.h51
-rw-r--r--src/server/collision/Management/MMapManager.cpp337
-rw-r--r--src/server/collision/Management/MMapManager.h90
-rw-r--r--src/server/collision/Management/VMapFactory.cpp42
-rw-r--r--src/server/collision/Management/VMapFactory.h40
-rw-r--r--src/server/collision/Management/VMapManager2.cpp329
-rw-r--r--src/server/collision/Management/VMapManager2.h142
-rw-r--r--src/server/collision/Maps/MapTree.cpp477
-rw-r--r--src/server/collision/Maps/MapTree.h103
-rw-r--r--src/server/collision/Maps/TileAssembler.cpp550
-rw-r--r--src/server/collision/Maps/TileAssembler.h119
-rw-r--r--src/server/collision/Models/GameObjectModel.cpp216
-rw-r--r--src/server/collision/Models/GameObjectModel.h87
-rw-r--r--src/server/collision/Models/ModelInstance.cpp222
-rw-r--r--src/server/collision/Models/ModelInstance.h82
-rw-r--r--src/server/collision/Models/WorldModel.cpp585
-rw-r--r--src/server/collision/Models/WorldModel.h129
-rw-r--r--src/server/collision/PrecompiledHeaders/collisionPCH.cpp1
-rw-r--r--src/server/collision/PrecompiledHeaders/collisionPCH.h9
-rw-r--r--src/server/collision/RegularGrid.h212
-rw-r--r--src/server/collision/VMapDefinitions.h47
-rw-r--r--src/server/collision/VMapTools.h150
-rw-r--r--src/server/database/CMakeLists.txt74
-rw-r--r--src/server/database/Database/AdhocStatement.cpp (renamed from src/server/shared/Database/AdhocStatement.cpp)0
-rw-r--r--src/server/database/Database/AdhocStatement.h (renamed from src/server/shared/Database/AdhocStatement.h)0
-rw-r--r--src/server/database/Database/DatabaseEnv.h (renamed from src/server/shared/Database/DatabaseEnv.h)0
-rw-r--r--src/server/database/Database/DatabaseLoader.cpp (renamed from src/server/shared/Database/DatabaseLoader.cpp)0
-rw-r--r--src/server/database/Database/DatabaseLoader.h (renamed from src/server/shared/Database/DatabaseLoader.h)0
-rw-r--r--src/server/database/Database/DatabaseWorker.cpp (renamed from src/server/shared/Database/DatabaseWorker.cpp)0
-rw-r--r--src/server/database/Database/DatabaseWorker.h (renamed from src/server/shared/Database/DatabaseWorker.h)0
-rw-r--r--src/server/database/Database/DatabaseWorkerPool.h (renamed from src/server/shared/Database/DatabaseWorkerPool.h)0
-rw-r--r--src/server/database/Database/Field.cpp (renamed from src/server/shared/Database/Field.cpp)0
-rw-r--r--src/server/database/Database/Field.h (renamed from src/server/shared/Database/Field.h)0
-rw-r--r--src/server/database/Database/Implementation/CharacterDatabase.cpp (renamed from src/server/shared/Database/Implementation/CharacterDatabase.cpp)0
-rw-r--r--src/server/database/Database/Implementation/CharacterDatabase.h (renamed from src/server/shared/Database/Implementation/CharacterDatabase.h)0
-rw-r--r--src/server/database/Database/Implementation/LoginDatabase.cpp (renamed from src/server/shared/Database/Implementation/LoginDatabase.cpp)0
-rw-r--r--src/server/database/Database/Implementation/LoginDatabase.h (renamed from src/server/shared/Database/Implementation/LoginDatabase.h)0
-rw-r--r--src/server/database/Database/Implementation/WorldDatabase.cpp (renamed from src/server/shared/Database/Implementation/WorldDatabase.cpp)0
-rw-r--r--src/server/database/Database/Implementation/WorldDatabase.h (renamed from src/server/shared/Database/Implementation/WorldDatabase.h)0
-rw-r--r--src/server/database/Database/MySQLConnection.cpp (renamed from src/server/shared/Database/MySQLConnection.cpp)0
-rw-r--r--src/server/database/Database/MySQLConnection.h (renamed from src/server/shared/Database/MySQLConnection.h)0
-rw-r--r--src/server/database/Database/MySQLThreading.h (renamed from src/server/shared/Database/MySQLThreading.h)0
-rw-r--r--src/server/database/Database/PreparedStatement.cpp (renamed from src/server/shared/Database/PreparedStatement.cpp)0
-rw-r--r--src/server/database/Database/PreparedStatement.h (renamed from src/server/shared/Database/PreparedStatement.h)0
-rw-r--r--src/server/database/Database/QueryHolder.cpp (renamed from src/server/shared/Database/QueryHolder.cpp)0
-rw-r--r--src/server/database/Database/QueryHolder.h (renamed from src/server/shared/Database/QueryHolder.h)0
-rw-r--r--src/server/database/Database/QueryResult.cpp (renamed from src/server/shared/Database/QueryResult.cpp)0
-rw-r--r--src/server/database/Database/QueryResult.h (renamed from src/server/shared/Database/QueryResult.h)0
-rw-r--r--src/server/database/Database/SQLOperation.h (renamed from src/server/shared/Database/SQLOperation.h)0
-rw-r--r--src/server/database/Database/Transaction.cpp (renamed from src/server/shared/Database/Transaction.cpp)0
-rw-r--r--src/server/database/Database/Transaction.h (renamed from src/server/shared/Database/Transaction.h)0
-rw-r--r--src/server/database/Logging/AppenderDB.cpp (renamed from src/server/shared/Logging/AppenderDB.cpp)0
-rw-r--r--src/server/database/Logging/AppenderDB.h (renamed from src/server/shared/Logging/AppenderDB.h)0
-rw-r--r--src/server/database/PrecompiledHeaders/databasePCH.cpp1
-rw-r--r--src/server/database/PrecompiledHeaders/databasePCH.h23
-rw-r--r--src/server/database/Updater/DBUpdater.cpp (renamed from src/server/shared/Updater/DBUpdater.cpp)0
-rw-r--r--src/server/database/Updater/DBUpdater.h (renamed from src/server/shared/Updater/DBUpdater.h)0
-rw-r--r--src/server/database/Updater/UpdateFetcher.cpp (renamed from src/server/shared/Updater/UpdateFetcher.cpp)0
-rw-r--r--src/server/database/Updater/UpdateFetcher.h (renamed from src/server/shared/Updater/UpdateFetcher.h)0
-rw-r--r--src/server/game/CMakeLists.txt25
-rw-r--r--src/server/scripts/CMakeLists.txt24
-rw-r--r--src/server/shared/CMakeLists.txt43
-rw-r--r--src/server/shared/Common.cpp41
-rw-r--r--src/server/shared/Common.h158
-rw-r--r--src/server/shared/CompilerDefs.h58
-rw-r--r--src/server/shared/Configuration/Config.cpp114
-rw-r--r--src/server/shared/Configuration/Config.h63
-rw-r--r--src/server/shared/Debugging/Errors.cpp75
-rw-r--r--src/server/shared/Debugging/Errors.h58
-rw-r--r--src/server/shared/Debugging/WheatyExceptionReport.cpp1423
-rw-r--r--src/server/shared/Debugging/WheatyExceptionReport.h210
-rw-r--r--src/server/shared/Define.h107
-rw-r--r--src/server/shared/Logging/Appender.cpp109
-rw-r--r--src/server/shared/Logging/Appender.h134
-rw-r--r--src/server/shared/Logging/AppenderConsole.cpp200
-rw-r--r--src/server/shared/Logging/AppenderConsole.h62
-rw-r--r--src/server/shared/Logging/AppenderFile.cpp124
-rw-r--r--src/server/shared/Logging/AppenderFile.h46
-rw-r--r--src/server/shared/Logging/Log.cpp348
-rw-r--r--src/server/shared/Logging/Log.h216
-rw-r--r--src/server/shared/Logging/LogOperation.cpp25
-rw-r--r--src/server/shared/Logging/LogOperation.h42
-rw-r--r--src/server/shared/Logging/Logger.cpp64
-rw-r--r--src/server/shared/Logging/Logger.h43
-rw-r--r--src/server/shared/PrecompiledHeaders/sharedPCH.h7
-rw-r--r--src/server/shared/Service/ServiceWin32.cpp (renamed from src/server/shared/Utilities/ServiceWin32.cpp)0
-rw-r--r--src/server/shared/Service/ServiceWin32.h (renamed from src/server/shared/Utilities/ServiceWin32.h)0
-rw-r--r--src/server/shared/Threading/Callback.h209
-rw-r--r--src/server/shared/Threading/LockedQueue.h144
-rw-r--r--src/server/shared/Threading/ProcessPriority.h105
-rw-r--r--src/server/shared/Threading/ProducerConsumerQueue.h112
-rw-r--r--src/server/shared/Utilities/ByteConverter.h68
-rw-r--r--src/server/shared/Utilities/Duration.h39
-rw-r--r--src/server/shared/Utilities/EventMap.cpp136
-rw-r--r--src/server/shared/Utilities/EventMap.h342
-rw-r--r--src/server/shared/Utilities/EventProcessor.cpp99
-rw-r--r--src/server/shared/Utilities/EventProcessor.h73
-rw-r--r--src/server/shared/Utilities/StringFormat.h46
-rw-r--r--src/server/shared/Utilities/TaskScheduler.cpp229
-rw-r--r--src/server/shared/Utilities/TaskScheduler.h650
-rw-r--r--src/server/shared/Utilities/Timer.h203
-rw-r--r--src/server/shared/Utilities/Util.cpp562
-rw-r--r--src/server/shared/Utilities/Util.h545
-rw-r--r--src/server/worldserver/CMakeLists.txt30
114 files changed, 190 insertions, 12786 deletions
diff --git a/src/server/CMakeLists.txt b/src/server/CMakeLists.txt
index fc4bf4328a3..5d3daef05d8 100644
--- a/src/server/CMakeLists.txt
+++ b/src/server/CMakeLists.txt
@@ -12,24 +12,20 @@
# This to stop a few silly crashes that could have been avoided IF people
# weren't doing some -O3 psychooptimizations etc.
+find_package(MySQL REQUIRED)
+
if(CMAKE_COMPILER_IS_GNUCXX AND NOT MINGW)
add_definitions(-fno-delete-null-pointer-checks)
endif()
-if( SERVERS )
- set(sources_windows_Debugging
- ${CMAKE_SOURCE_DIR}/src/server/shared/Debugging/WheatyExceptionReport.cpp
- ${CMAKE_SOURCE_DIR}/src/server/shared/Debugging/WheatyExceptionReport.h
- )
- add_subdirectory(shared)
- add_subdirectory(game)
- add_subdirectory(collision)
- add_subdirectory(authserver)
- add_subdirectory(scripts)
- add_subdirectory(worldserver)
-else()
- if( TOOLS )
- add_subdirectory(collision)
- add_subdirectory(shared)
- endif()
-endif()
+set(sources_windows_Debugging
+ ${CMAKE_SOURCE_DIR}/src/common/Debugging/WheatyExceptionReport.cpp
+ ${CMAKE_SOURCE_DIR}/src/common/Debugging/WheatyExceptionReport.h
+)
+add_subdirectory(database)
+add_subdirectory(shared)
+add_subdirectory(game)
+add_subdirectory(authserver)
+add_subdirectory(scripts)
+add_subdirectory(worldserver)
+
diff --git a/src/server/authserver/CMakeLists.txt b/src/server/authserver/CMakeLists.txt
index f6d99de5271..24a2dc35fce 100644
--- a/src/server/authserver/CMakeLists.txt
+++ b/src/server/authserver/CMakeLists.txt
@@ -45,22 +45,29 @@ include_directories(
${CMAKE_BINARY_DIR}
${CMAKE_SOURCE_DIR}/dep/cppformat
${CMAKE_SOURCE_DIR}/dep/process
+ ${CMAKE_SOURCE_DIR}/src/server/database
+ ${CMAKE_SOURCE_DIR}/src/server/database/Database
+ ${CMAKE_SOURCE_DIR}/src/server/database/Logging
+ ${CMAKE_SOURCE_DIR}/src/server/database/Updater
${CMAKE_SOURCE_DIR}/src/server/shared
- ${CMAKE_SOURCE_DIR}/src/server/shared/Configuration
- ${CMAKE_SOURCE_DIR}/src/server/shared/Database
- ${CMAKE_SOURCE_DIR}/src/server/shared/Debugging
${CMAKE_SOURCE_DIR}/src/server/shared/Packets
${CMAKE_SOURCE_DIR}/src/server/shared/Cryptography
${CMAKE_SOURCE_DIR}/src/server/shared/Cryptography/Authentication
- ${CMAKE_SOURCE_DIR}/src/server/shared/Logging
${CMAKE_SOURCE_DIR}/src/server/shared/Networking
- ${CMAKE_SOURCE_DIR}/src/server/shared/Threading
- ${CMAKE_SOURCE_DIR}/src/server/shared/Updater
- ${CMAKE_SOURCE_DIR}/src/server/shared/Utilities
+ ${CMAKE_SOURCE_DIR}/src/server/shared/Service
${CMAKE_CURRENT_SOURCE_DIR}
${CMAKE_CURRENT_SOURCE_DIR}/Authentication
${CMAKE_CURRENT_SOURCE_DIR}/Realms
${CMAKE_CURRENT_SOURCE_DIR}/Server
+ ${CMAKE_SOURCE_DIR}/src/common/
+ ${CMAKE_SOURCE_DIR}/src/common/Collision
+ ${CMAKE_SOURCE_DIR}/src/common/Collision/Management
+ ${CMAKE_SOURCE_DIR}/src/common/Collision/Models
+ ${CMAKE_SOURCE_DIR}/src/common/Debugging
+ ${CMAKE_SOURCE_DIR}/src/common/Utilities
+ ${CMAKE_SOURCE_DIR}/src/common/Threading
+ ${CMAKE_SOURCE_DIR}/src/common/Configuration
+ ${CMAKE_SOURCE_DIR}/src/common/Logging
${MYSQL_INCLUDE_DIR}
${OPENSSL_INCLUDE_DIR}
${VALGRIND_INCLUDE_DIR}
@@ -80,8 +87,10 @@ if( NOT WIN32 )
endif()
target_link_libraries(authserver
+ common
shared
format
+ database
${MYSQL_LIBRARY}
${OPENSSL_LIBRARIES}
${CMAKE_THREAD_LIBS_INIT}
diff --git a/src/server/collision/BoundingIntervalHierarchy.cpp b/src/server/collision/BoundingIntervalHierarchy.cpp
deleted file mode 100644
index 12af680712e..00000000000
--- a/src/server/collision/BoundingIntervalHierarchy.cpp
+++ /dev/null
@@ -1,310 +0,0 @@
-/*
- * Copyright (C) 2008-2015 TrinityCore <http://www.trinitycore.org/>
- * 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, see <http://www.gnu.org/licenses/>.
- */
-
-#include "BoundingIntervalHierarchy.h"
-
-#ifdef _MSC_VER
- #define isnan _isnan
-#else
- #define isnan std::isnan
-#endif
-
-void BIH::buildHierarchy(std::vector<uint32> &tempTree, buildData &dat, BuildStats &stats)
-{
- // create space for the first node
- tempTree.push_back(uint32(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
- G3D::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::finf();
- clipR = G3D::finf();
- rightOrig = right; // save this for later
- float nodeL = G3D::finf();
- float nodeR = -G3D::finf();
- 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 && G3D::fuzzyEq(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 && G3D::fuzzyEq(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::finf());
- } 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::finf());
- 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;
- 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;
- G3D::Vector3 lo, hi;
- uint32 check=0, count=0;
- check += fread(&lo, sizeof(float), 3, rf);
- check += fread(&hi, sizeof(float), 3, rf);
- bounds = G3D::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 uint64(check) == uint64(3 + 3 + 1 + 1 + uint64(treeSize) + uint64(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));
-}
diff --git a/src/server/collision/BoundingIntervalHierarchy.h b/src/server/collision/BoundingIntervalHierarchy.h
deleted file mode 100644
index 3a09772c41f..00000000000
--- a/src/server/collision/BoundingIntervalHierarchy.h
+++ /dev/null
@@ -1,400 +0,0 @@
-/*
- * Copyright (C) 2008-2015 TrinityCore <http://www.trinitycore.org/>
- * 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, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef _BIH_H
-#define _BIH_H
-
-#include "G3D/Vector3.h"
-#include "G3D/Ray.h"
-#include "G3D/AABox.h"
-
-#include "Define.h"
-
-#include <stdexcept>
-#include <vector>
-#include <algorithm>
-#include <limits>
-#include <cmath>
-
-#define MAX_STACK_SIZE 64
-
-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
-{
- G3D::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
-{
- private:
- void init_empty()
- {
- tree.clear();
- objects.clear();
- // create space for the first node
- tree.push_back(3u << 30u); // dummy leaf
- tree.insert(tree.end(), 2, 0);
- }
- public:
- BIH() { init_empty(); }
- template< class BoundsFunc, class PrimArray >
- void build(const PrimArray &primitives, BoundsFunc &getBounds, uint32 leafSize = 3, bool printStats=false)
- {
- if (primitives.size() == 0)
- {
- init_empty();
- return;
- }
-
- buildData dat;
- dat.maxPrims = leafSize;
- dat.numPrims = primitives.size();
- dat.indices = new uint32[dat.numPrims];
- dat.primBound = new G3D::AABox[dat.numPrims];
- getBounds(primitives[0], bounds);
- for (uint32 i=0; i<dat.numPrims; ++i)
- {
- dat.indices[i] = i;
- 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() const { return objects.size(); }
-
- template<typename RayCallback>
- void intersectRay(const G3D::Ray &r, RayCallback& intersectCallback, float &maxDist, bool stopAtFirst=false) const
- {
- float intervalMin = -1.f;
- float intervalMax = -1.f;
- G3D::Vector3 org = r.origin();
- G3D::Vector3 dir = r.direction();
- G3D::Vector3 invDir;
- for (int i=0; i<3; ++i)
- {
- invDir[i] = 1.f / dir[i];
- if (G3D::fuzzyNe(dir[i], 0.0f))
- {
- float t1 = (bounds.low()[i] - org[i]) * invDir[i];
- float t2 = (bounds.high()[i] - org[i]) * invDir[i];
- if (t1 > t2)
- std::swap(t1, t2);
- if (t1 > intervalMin)
- intervalMin = t1;
- if (t2 < intervalMax || intervalMax < 0.f)
- intervalMax = t2;
- // intervalMax can only become smaller for other axis,
- // and intervalMin only larger respectively, so stop early
- if (intervalMax <= 0 || intervalMin >= maxDist)
- return;
- }
- }
-
- if (intervalMin > intervalMax)
- return;
- intervalMin = std::max(intervalMin, 0.f);
- intervalMax = std::min(intervalMax, maxDist);
-
- 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)) != 0;
- 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 G3D::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)) != 0;
- 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;
- G3D::AABox bounds;
-
- struct buildData
- {
- uint32 *indices;
- G3D::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) const
- {
- // 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
diff --git a/src/server/collision/BoundingIntervalHierarchyWrapper.h b/src/server/collision/BoundingIntervalHierarchyWrapper.h
deleted file mode 100644
index 60bb6a569df..00000000000
--- a/src/server/collision/BoundingIntervalHierarchyWrapper.h
+++ /dev/null
@@ -1,119 +0,0 @@
-/*
- * Copyright (C) 2008-2015 TrinityCore <http://www.trinitycore.org/>
- * 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, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef _BIH_WRAP
-#define _BIH_WRAP
-
-#include "G3D/Table.h"
-#include "G3D/Array.h"
-#include "G3D/Set.h"
-#include "BoundingIntervalHierarchy.h"
-
-
-template<class T, class BoundsFunc = BoundsTrait<T> >
-class BIHWrap
-{
- template<class RayCallback>
- struct MDLCallback
- {
- const T* const* objects;
- RayCallback& _callback;
- uint32 objects_size;
-
- MDLCallback(RayCallback& callback, const T* const* objects_array, uint32 objects_size ) : objects(objects_array), _callback(callback), objects_size(objects_size) { }
-
- /// Intersect ray
- bool operator() (const G3D::Ray& ray, uint32 idx, float& maxDist, bool /*stopAtFirst*/)
- {
- if (idx >= objects_size)
- return false;
- if (const T* obj = objects[idx])
- return _callback(ray, *obj, maxDist/*, stopAtFirst*/);
- return false;
- }
-
- /// Intersect point
- void operator() (const G3D::Vector3& p, uint32 idx)
- {
- if (idx >= objects_size)
- return;
- if (const T* obj = objects[idx])
- _callback(p, *obj);
- }
- };
-
- typedef G3D::Array<const T*> ObjArray;
-
- BIH m_tree;
- ObjArray m_objects;
- G3D::Table<const T*, uint32> m_obj2Idx;
- G3D::Set<const T*> m_objects_to_push;
- int unbalanced_times;
-
-public:
- BIHWrap() : unbalanced_times(0) { }
-
- void insert(const T& obj)
- {
- ++unbalanced_times;
- m_objects_to_push.insert(&obj);
- }
-
- void remove(const T& obj)
- {
- ++unbalanced_times;
- uint32 Idx = 0;
- const T * temp;
- if (m_obj2Idx.getRemove(&obj, temp, Idx))
- m_objects[Idx] = NULL;
- else
- m_objects_to_push.remove(&obj);
- }
-
- void balance()
- {
- if (unbalanced_times == 0)
- return;
-
- unbalanced_times = 0;
- m_objects.fastClear();
- m_obj2Idx.getKeys(m_objects);
- m_objects_to_push.getMembers(m_objects);
- //assert that m_obj2Idx has all the keys
-
- m_tree.build(m_objects, BoundsFunc::getBounds2);
- }
-
- template<typename RayCallback>
- void intersectRay(const G3D::Ray& ray, RayCallback& intersectCallback, float& maxDist)
- {
- balance();
- MDLCallback<RayCallback> temp_cb(intersectCallback, m_objects.getCArray(), m_objects.size());
- m_tree.intersectRay(ray, temp_cb, maxDist, true);
- }
-
- template<typename IsectCallback>
- void intersectPoint(const G3D::Vector3& point, IsectCallback& intersectCallback)
- {
- balance();
- MDLCallback<IsectCallback> callback(intersectCallback, m_objects.getCArray(), m_objects.size());
- m_tree.intersectPoint(point, callback);
- }
-};
-
-#endif // _BIH_WRAP
diff --git a/src/server/collision/CMakeLists.txt b/src/server/collision/CMakeLists.txt
deleted file mode 100644
index f394fe791be..00000000000
--- a/src/server/collision/CMakeLists.txt
+++ /dev/null
@@ -1,97 +0,0 @@
-# Copyright (C) 2008-2015 TrinityCore <http://www.trinitycore.org/>
-#
-# This file is free software; as a special exception the author gives
-# unlimited permission to copy and/or distribute it, with or without
-# modifications, as long as this notice is preserved.
-#
-# This program is distributed in the hope that it will be useful, but
-# WITHOUT ANY WARRANTY, to the extent permitted by law; without even the
-# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-
-if( USE_COREPCH )
- include_directories(${CMAKE_CURRENT_BINARY_DIR})
-endif()
-
-file(GLOB_RECURSE sources_Management Management/*.cpp Management/*.h)
-file(GLOB_RECURSE sources_Maps Maps/*.cpp Maps/*.h)
-file(GLOB_RECURSE sources_Models Models/*.cpp Models/*.h)
-file(GLOB sources_localdir *.cpp *.h)
-
-if (USE_COREPCH)
- set(collision_STAT_PCH_HDR PrecompiledHeaders/collisionPCH.h)
- set(collision_STAT_PCH_SRC PrecompiledHeaders/collisionPCH.cpp)
-endif ()
-
-set(collision_STAT_SRCS
- ${collision_STAT_SRCS}
- ${sources_Management}
- ${sources_Maps}
- ${sources_Models}
- ${sources_localdir}
-)
-
-include_directories(
- ${CMAKE_BINARY_DIR}
- ${CMAKE_SOURCE_DIR}/dep/g3dlite/include
- ${CMAKE_SOURCE_DIR}/dep/recastnavigation/Detour
- ${CMAKE_SOURCE_DIR}/dep/recastnavigation/Detour/Include
- ${CMAKE_SOURCE_DIR}/dep/cppformat
- ${CMAKE_SOURCE_DIR}/src/server/shared
- ${CMAKE_SOURCE_DIR}/src/server/shared/Configuration
- ${CMAKE_SOURCE_DIR}/src/server/shared/Debugging
- ${CMAKE_SOURCE_DIR}/src/server/shared/Database
- ${CMAKE_SOURCE_DIR}/src/server/shared/Debugging
- ${CMAKE_SOURCE_DIR}/src/server/shared/Dynamic
- ${CMAKE_SOURCE_DIR}/src/server/shared/Dynamic/LinkedReference
- ${CMAKE_SOURCE_DIR}/src/server/shared/Logging
- ${CMAKE_SOURCE_DIR}/src/server/shared/Threading
- ${CMAKE_SOURCE_DIR}/src/server/shared/Packets
- ${CMAKE_SOURCE_DIR}/src/server/shared/Utilities
- ${CMAKE_SOURCE_DIR}/src/server/shared/DataStores
- ${CMAKE_SOURCE_DIR}/src/server/game/Addons
- ${CMAKE_SOURCE_DIR}/src/server/game/Conditions
- ${CMAKE_SOURCE_DIR}/src/server/game/Entities/Item
- ${CMAKE_SOURCE_DIR}/src/server/game/Entities/GameObject
- ${CMAKE_SOURCE_DIR}/src/server/game/Entities/Creature
- ${CMAKE_SOURCE_DIR}/src/server/game/Entities/Object
- ${CMAKE_SOURCE_DIR}/src/server/game/Entities/Object/Updates
- ${CMAKE_SOURCE_DIR}/src/server/game/Entities/Unit
- ${CMAKE_SOURCE_DIR}/src/server/game/Combat
- ${CMAKE_SOURCE_DIR}/src/server/game/Loot
- ${CMAKE_SOURCE_DIR}/src/server/game/Miscellaneous
- ${CMAKE_SOURCE_DIR}/src/server/game/Grids
- ${CMAKE_SOURCE_DIR}/src/server/game/Grids/Cells
- ${CMAKE_SOURCE_DIR}/src/server/game/Grids/Notifiers
- ${CMAKE_SOURCE_DIR}/src/server/game/Maps
- ${CMAKE_SOURCE_DIR}/src/server/game/DataStores
- ${CMAKE_SOURCE_DIR}/src/server/game/Movement/Waypoints
- ${CMAKE_SOURCE_DIR}/src/server/game/Movement/Spline
- ${CMAKE_SOURCE_DIR}/src/server/game/Movement
- ${CMAKE_SOURCE_DIR}/src/server/game/Server
- ${CMAKE_SOURCE_DIR}/src/server/game/Server/Protocol
- ${CMAKE_SOURCE_DIR}/src/server/game/World
- ${CMAKE_SOURCE_DIR}/src/server/game/Spells
- ${CMAKE_SOURCE_DIR}/src/server/game/Spells/Auras
- ${CMAKE_CURRENT_SOURCE_DIR}
- ${CMAKE_CURRENT_SOURCE_DIR}/Management
- ${CMAKE_CURRENT_SOURCE_DIR}/Maps
- ${CMAKE_CURRENT_SOURCE_DIR}/Models
- ${MYSQL_INCLUDE_DIR}
- ${VALGRIND_INCLUDE_DIR}
-)
-
-GroupSources(${CMAKE_CURRENT_SOURCE_DIR})
-
-add_library(collision STATIC
- ${collision_STAT_SRCS}
- ${collision_STAT_PCH_SRC}
-)
-
-target_link_libraries(collision
- shared
-)
-
-# Generate precompiled header
-if (USE_COREPCH)
- add_cxx_pch(collision ${collision_STAT_PCH_HDR} ${collision_STAT_PCH_SRC})
-endif ()
diff --git a/src/server/collision/DynamicTree.cpp b/src/server/collision/DynamicTree.cpp
deleted file mode 100644
index 1de2543543d..00000000000
--- a/src/server/collision/DynamicTree.cpp
+++ /dev/null
@@ -1,260 +0,0 @@
-/*
- * Copyright (C) 2008-2015 TrinityCore <http://www.trinitycore.org/>
- * 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, see <http://www.gnu.org/licenses/>.
- */
-
-#include "DynamicTree.h"
-//#include "QuadTree.h"
-//#include "RegularGrid.h"
-#include "BoundingIntervalHierarchyWrapper.h"
-
-#include "Log.h"
-#include "RegularGrid.h"
-#include "Timer.h"
-#include "GameObjectModel.h"
-#include "ModelInstance.h"
-
-#include <G3D/AABox.h>
-#include <G3D/Ray.h>
-#include <G3D/Vector3.h>
-
-using VMAP::ModelInstance;
-
-namespace {
-
-int CHECK_TREE_PERIOD = 200;
-
-} // namespace
-
-template<> struct HashTrait< GameObjectModel>{
- static size_t hashCode(const GameObjectModel& g) { return (size_t)(void*)&g; }
-};
-
-template<> struct PositionTrait< GameObjectModel> {
- static void getPosition(const GameObjectModel& g, G3D::Vector3& p) { p = g.getPosition(); }
-};
-
-template<> struct BoundsTrait< GameObjectModel> {
- static void getBounds(const GameObjectModel& g, G3D::AABox& out) { out = g.getBounds();}
- static void getBounds2(const GameObjectModel* g, G3D::AABox& out) { out = g->getBounds();}
-};
-
-/*
-static bool operator == (const GameObjectModel& mdl, const GameObjectModel& mdl2){
- return &mdl == &mdl2;
-}
-*/
-
-typedef RegularGrid2D<GameObjectModel, BIHWrap<GameObjectModel> > ParentTree;
-
-struct DynTreeImpl : public ParentTree/*, public Intersectable*/
-{
- typedef GameObjectModel Model;
- typedef ParentTree base;
-
- DynTreeImpl() :
- rebalance_timer(CHECK_TREE_PERIOD),
- unbalanced_times(0)
- {
- }
-
- void insert(const Model& mdl)
- {
- base::insert(mdl);
- ++unbalanced_times;
- }
-
- void remove(const Model& mdl)
- {
- base::remove(mdl);
- ++unbalanced_times;
- }
-
- void balance()
- {
- base::balance();
- unbalanced_times = 0;
- }
-
- void update(uint32 difftime)
- {
- if (!size())
- return;
-
- rebalance_timer.Update(difftime);
- if (rebalance_timer.Passed())
- {
- rebalance_timer.Reset(CHECK_TREE_PERIOD);
- if (unbalanced_times > 0)
- balance();
- }
- }
-
- TimeTrackerSmall rebalance_timer;
- int unbalanced_times;
-};
-
-DynamicMapTree::DynamicMapTree() : impl(new DynTreeImpl()) { }
-
-DynamicMapTree::~DynamicMapTree()
-{
- delete impl;
-}
-
-void DynamicMapTree::insert(const GameObjectModel& mdl)
-{
- impl->insert(mdl);
-}
-
-void DynamicMapTree::remove(const GameObjectModel& mdl)
-{
- impl->remove(mdl);
-}
-
-bool DynamicMapTree::contains(const GameObjectModel& mdl) const
-{
- return impl->contains(mdl);
-}
-
-void DynamicMapTree::balance()
-{
- impl->balance();
-}
-
-int DynamicMapTree::size() const
-{
- return impl->size();
-}
-
-void DynamicMapTree::update(uint32 t_diff)
-{
- impl->update(t_diff);
-}
-
-struct DynamicTreeIntersectionCallback
-{
- bool did_hit;
- uint32 phase_mask;
- DynamicTreeIntersectionCallback(uint32 phasemask) : did_hit(false), phase_mask(phasemask) { }
- bool operator()(const G3D::Ray& r, const GameObjectModel& obj, float& distance)
- {
- did_hit = obj.intersectRay(r, distance, true, phase_mask);
- return did_hit;
- }
- bool didHit() const { return did_hit;}
-};
-
-struct DynamicTreeIntersectionCallback_WithLogger
-{
- bool did_hit;
- uint32 phase_mask;
- DynamicTreeIntersectionCallback_WithLogger(uint32 phasemask) : did_hit(false), phase_mask(phasemask)
- {
- TC_LOG_DEBUG("maps", "Dynamic Intersection log");
- }
- bool operator()(const G3D::Ray& r, const GameObjectModel& obj, float& distance)
- {
- TC_LOG_DEBUG("maps", "testing intersection with %s", obj.name.c_str());
- bool hit = obj.intersectRay(r, distance, true, phase_mask);
- if (hit)
- {
- did_hit = true;
- TC_LOG_DEBUG("maps", "result: intersects");
- }
- return hit;
- }
- bool didHit() const { return did_hit;}
-};
-
-bool DynamicMapTree::getIntersectionTime(const uint32 phasemask, const G3D::Ray& ray,
- const G3D::Vector3& endPos, float& maxDist) const
-{
- float distance = maxDist;
- DynamicTreeIntersectionCallback callback(phasemask);
- impl->intersectRay(ray, callback, distance, endPos);
- if (callback.didHit())
- maxDist = distance;
- return callback.didHit();
-}
-
-bool DynamicMapTree::getObjectHitPos(const uint32 phasemask, const G3D::Vector3& startPos,
- const G3D::Vector3& endPos, G3D::Vector3& resultHit,
- float modifyDist) const
-{
- bool result = false;
- float maxDist = (endPos - startPos).magnitude();
- // valid map coords should *never ever* produce float overflow, but this would produce NaNs too
- ASSERT(maxDist < std::numeric_limits<float>::max());
- // prevent NaN values which can cause BIH intersection to enter infinite loop
- if (maxDist < 1e-10f)
- {
- resultHit = endPos;
- return false;
- }
- G3D::Vector3 dir = (endPos - startPos)/maxDist; // direction with length of 1
- G3D::Ray ray(startPos, dir);
- float dist = maxDist;
- if (getIntersectionTime(phasemask, ray, endPos, dist))
- {
- resultHit = startPos + dir * dist;
- if (modifyDist < 0)
- {
- if ((resultHit - startPos).magnitude() > -modifyDist)
- resultHit = resultHit + dir*modifyDist;
- else
- resultHit = startPos;
- }
- else
- resultHit = resultHit + dir*modifyDist;
-
- result = true;
- }
- else
- {
- resultHit = endPos;
- result = false;
- }
- return result;
-}
-
-bool DynamicMapTree::isInLineOfSight(float x1, float y1, float z1, float x2, float y2, float z2, uint32 phasemask) const
-{
- G3D::Vector3 v1(x1, y1, z1), v2(x2, y2, z2);
-
- float maxDist = (v2 - v1).magnitude();
-
- if (!G3D::fuzzyGt(maxDist, 0) )
- return true;
-
- G3D::Ray r(v1, (v2-v1) / maxDist);
- DynamicTreeIntersectionCallback callback(phasemask);
- impl->intersectRay(r, callback, maxDist, v2);
-
- return !callback.did_hit;
-}
-
-float DynamicMapTree::getHeight(float x, float y, float z, float maxSearchDist, uint32 phasemask) const
-{
- G3D::Vector3 v(x, y, z);
- G3D::Ray r(v, G3D::Vector3(0, 0, -1));
- DynamicTreeIntersectionCallback callback(phasemask);
- impl->intersectZAllignedRay(r, callback, maxSearchDist);
-
- if (callback.didHit())
- return v.z - maxSearchDist;
- else
- return -G3D::finf();
-}
diff --git a/src/server/collision/DynamicTree.h b/src/server/collision/DynamicTree.h
deleted file mode 100644
index 5e905323640..00000000000
--- a/src/server/collision/DynamicTree.h
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * Copyright (C) 2008-2015 TrinityCore <http://www.trinitycore.org/>
- * 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, see <http://www.gnu.org/licenses/>.
- */
-
-
-#ifndef _DYNTREE_H
-#define _DYNTREE_H
-
-#include "Define.h"
-
-namespace G3D
-{
- class Ray;
- class Vector3;
-}
-
-class GameObjectModel;
-struct DynTreeImpl;
-
-class DynamicMapTree
-{
- DynTreeImpl *impl;
-
-public:
-
- DynamicMapTree();
- ~DynamicMapTree();
-
- bool isInLineOfSight(float x1, float y1, float z1, float x2, float y2,
- float z2, uint32 phasemask) const;
-
- bool getIntersectionTime(uint32 phasemask, const G3D::Ray& ray,
- const G3D::Vector3& endPos, float& maxDist) const;
-
- bool getObjectHitPos(uint32 phasemask, const G3D::Vector3& pPos1,
- const G3D::Vector3& pPos2, G3D::Vector3& pResultHitPos,
- float pModifyDist) const;
-
- float getHeight(float x, float y, float z, float maxSearchDist, uint32 phasemask) const;
-
- void insert(const GameObjectModel&);
- void remove(const GameObjectModel&);
- bool contains(const GameObjectModel&) const;
- int size() const;
-
- void balance();
- void update(uint32 diff);
-};
-
-#endif // _DYNTREE_H
diff --git a/src/server/collision/Management/IVMapManager.h b/src/server/collision/Management/IVMapManager.h
deleted file mode 100644
index b890554257c..00000000000
--- a/src/server/collision/Management/IVMapManager.h
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
- * Copyright (C) 2008-2015 TrinityCore <http://www.trinitycore.org/>
- * 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, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef _IVMAPMANAGER_H
-#define _IVMAPMANAGER_H
-
-#include <string>
-#include "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, float maxSearchDist) = 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;
- /**
- 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
diff --git a/src/server/collision/Management/MMapFactory.cpp b/src/server/collision/Management/MMapFactory.cpp
deleted file mode 100644
index 667b8378c56..00000000000
--- a/src/server/collision/Management/MMapFactory.cpp
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * Copyright (C) 2008-2015 TrinityCore <http://www.trinitycore.org/>
- * 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, see <http://www.gnu.org/licenses/>.
- */
-
-#include "MMapFactory.h"
-#include "Config.h"
-
-namespace MMAP
-{
- // ######################## MMapFactory ########################
- // our global singleton copy
- MMapManager* g_MMapManager = NULL;
-
- MMapManager* MMapFactory::createOrGetMMapManager()
- {
- if (g_MMapManager == NULL)
- g_MMapManager = new MMapManager();
-
- return g_MMapManager;
- }
-
- void MMapFactory::clear()
- {
- if (g_MMapManager)
- {
- delete g_MMapManager;
- g_MMapManager = NULL;
- }
- }
-} \ No newline at end of file
diff --git a/src/server/collision/Management/MMapFactory.h b/src/server/collision/Management/MMapFactory.h
deleted file mode 100644
index 773983f81eb..00000000000
--- a/src/server/collision/Management/MMapFactory.h
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * Copyright (C) 2008-2015 TrinityCore <http://www.trinitycore.org/>
- * 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, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef _MMAP_FACTORY_H
-#define _MMAP_FACTORY_H
-
-#include "Define.h"
-#include "MMapManager.h"
-#include "DetourAlloc.h"
-#include "DetourNavMesh.h"
-#include "DetourNavMeshQuery.h"
-#include <unordered_map>
-
-namespace MMAP
-{
- enum MMAP_LOAD_RESULT
- {
- MMAP_LOAD_RESULT_ERROR,
- MMAP_LOAD_RESULT_OK,
- MMAP_LOAD_RESULT_IGNORED
- };
-
- // static class
- // holds all mmap global data
- // access point to MMapManager singleton
- class MMapFactory
- {
- public:
- static MMapManager* createOrGetMMapManager();
- static void clear();
- static bool IsPathfindingEnabled(uint32 mapId);
- };
-}
-
-#endif
-
diff --git a/src/server/collision/Management/MMapManager.cpp b/src/server/collision/Management/MMapManager.cpp
deleted file mode 100644
index b71b94e3291..00000000000
--- a/src/server/collision/Management/MMapManager.cpp
+++ /dev/null
@@ -1,337 +0,0 @@
-/*
- * Copyright (C) 2008-2015 TrinityCore <http://www.trinitycore.org/>
- * 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, see <http://www.gnu.org/licenses/>.
- */
-
-#include "MMapManager.h"
-#include "Log.h"
-#include "World.h"
-
-namespace MMAP
-{
- // ######################## MMapManager ########################
- MMapManager::~MMapManager()
- {
- for (MMapDataSet::iterator i = loadedMMaps.begin(); i != loadedMMaps.end(); ++i)
- delete i->second;
-
- // by now we should not have maps loaded
- // if we had, tiles in MMapData->mmapLoadedTiles, their actual data is lost!
- }
-
- void MMapManager::InitializeThreadUnsafe(const std::vector<uint32>& mapIds)
- {
- // the caller must pass the list of all mapIds that will be used in the VMapManager2 lifetime
- for (const uint32& mapId : mapIds)
- loadedMMaps.insert(MMapDataSet::value_type(mapId, nullptr));
-
- thread_safe_environment = false;
- }
-
- MMapDataSet::const_iterator MMapManager::GetMMapData(uint32 mapId) const
- {
- // return the iterator if found or end() if not found/NULL
- MMapDataSet::const_iterator itr = loadedMMaps.find(mapId);
- if (itr != loadedMMaps.cend() && !itr->second)
- itr = loadedMMaps.cend();
-
- return itr;
- }
-
- bool MMapManager::loadMapData(uint32 mapId)
- {
- // we already have this map loaded?
- MMapDataSet::iterator itr = loadedMMaps.find(mapId);
- if (itr != loadedMMaps.end())
- {
- if (itr->second)
- return true;
- }
- else
- {
- if (thread_safe_environment)
- itr = loadedMMaps.insert(MMapDataSet::value_type(mapId, nullptr)).first;
- else
- ASSERT(false, "Invalid mapId %u passed to MMapManager after startup in thread unsafe environment", mapId);
- }
-
- // load and init dtNavMesh - read parameters from file
- uint32 pathLen = sWorld->GetDataPath().length() + strlen("mmaps/%03i.mmap")+1;
- char *fileName = new char[pathLen];
- snprintf(fileName, pathLen, (sWorld->GetDataPath()+"mmaps/%03i.mmap").c_str(), mapId);
-
- FILE* file = fopen(fileName, "rb");
- if (!file)
- {
- TC_LOG_DEBUG("maps", "MMAP:loadMapData: Error: Could not open mmap file '%s'", fileName);
- delete [] fileName;
- return false;
- }
-
- dtNavMeshParams params;
- int count = fread(&params, sizeof(dtNavMeshParams), 1, file);
- fclose(file);
- if (count != 1)
- {
- TC_LOG_DEBUG("maps", "MMAP:loadMapData: Error: Could not read params from file '%s'", fileName);
- delete [] fileName;
- return false;
- }
-
- dtNavMesh* mesh = dtAllocNavMesh();
- ASSERT(mesh);
- if (dtStatusFailed(mesh->init(&params)))
- {
- dtFreeNavMesh(mesh);
- TC_LOG_ERROR("maps", "MMAP:loadMapData: Failed to initialize dtNavMesh for mmap %03u from file %s", mapId, fileName);
- delete [] fileName;
- return false;
- }
-
- delete [] fileName;
-
- TC_LOG_DEBUG("maps", "MMAP:loadMapData: Loaded %03i.mmap", mapId);
-
- // store inside our map list
- MMapData* mmap_data = new MMapData(mesh);
- mmap_data->mmapLoadedTiles.clear();
-
- itr->second = mmap_data;
- return true;
- }
-
- uint32 MMapManager::packTileID(int32 x, int32 y)
- {
- return uint32(x << 16 | y);
- }
-
- bool MMapManager::loadMap(const std::string& /*basePath*/, uint32 mapId, int32 x, int32 y)
- {
- // make sure the mmap is loaded and ready to load tiles
- if (!loadMapData(mapId))
- return false;
-
- // get this mmap data
- MMapData* mmap = loadedMMaps[mapId];
- ASSERT(mmap->navMesh);
-
- // check if we already have this tile loaded
- uint32 packedGridPos = packTileID(x, y);
- if (mmap->mmapLoadedTiles.find(packedGridPos) != mmap->mmapLoadedTiles.end())
- return false;
-
- // load this tile :: mmaps/MMMXXYY.mmtile
- uint32 pathLen = sWorld->GetDataPath().length() + strlen("mmaps/%03i%02i%02i.mmtile")+1;
- char *fileName = new char[pathLen];
-
- snprintf(fileName, pathLen, (sWorld->GetDataPath()+"mmaps/%03i%02i%02i.mmtile").c_str(), mapId, x, y);
-
- FILE* file = fopen(fileName, "rb");
- if (!file)
- {
- TC_LOG_DEBUG("maps", "MMAP:loadMap: Could not open mmtile file '%s'", fileName);
- delete [] fileName;
- return false;
- }
- delete [] fileName;
-
- // read header
- MmapTileHeader fileHeader;
- if (fread(&fileHeader, sizeof(MmapTileHeader), 1, file) != 1 || fileHeader.mmapMagic != MMAP_MAGIC)
- {
- TC_LOG_ERROR("maps", "MMAP:loadMap: Bad header in mmap %03u%02i%02i.mmtile", mapId, x, y);
- fclose(file);
- return false;
- }
-
- if (fileHeader.mmapVersion != MMAP_VERSION)
- {
- TC_LOG_ERROR("maps", "MMAP:loadMap: %03u%02i%02i.mmtile was built with generator v%i, expected v%i",
- mapId, x, y, fileHeader.mmapVersion, MMAP_VERSION);
- fclose(file);
- return false;
- }
-
- unsigned char* data = (unsigned char*)dtAlloc(fileHeader.size, DT_ALLOC_PERM);
- ASSERT(data);
-
- size_t result = fread(data, fileHeader.size, 1, file);
- if (!result)
- {
- TC_LOG_ERROR("maps", "MMAP:loadMap: Bad header or data in mmap %03u%02i%02i.mmtile", mapId, x, y);
- fclose(file);
- return false;
- }
-
- fclose(file);
-
- dtMeshHeader* header = (dtMeshHeader*)data;
- dtTileRef tileRef = 0;
-
- // memory allocated for data is now managed by detour, and will be deallocated when the tile is removed
- if (dtStatusSucceed(mmap->navMesh->addTile(data, fileHeader.size, DT_TILE_FREE_DATA, 0, &tileRef)))
- {
- mmap->mmapLoadedTiles.insert(std::pair<uint32, dtTileRef>(packedGridPos, tileRef));
- ++loadedTiles;
- TC_LOG_DEBUG("maps", "MMAP:loadMap: Loaded mmtile %03i[%02i, %02i] into %03i[%02i, %02i]", mapId, x, y, mapId, header->x, header->y);
- return true;
- }
- else
- {
- TC_LOG_ERROR("maps", "MMAP:loadMap: Could not load %03u%02i%02i.mmtile into navmesh", mapId, x, y);
- dtFree(data);
- return false;
- }
- }
-
- bool MMapManager::unloadMap(uint32 mapId, int32 x, int32 y)
- {
- // check if we have this map loaded
- MMapDataSet::const_iterator itr = GetMMapData(mapId);
- if (itr == loadedMMaps.end())
- {
- // file may not exist, therefore not loaded
- TC_LOG_DEBUG("maps", "MMAP:unloadMap: Asked to unload not loaded navmesh map. %03u%02i%02i.mmtile", mapId, x, y);
- return false;
- }
-
- MMapData* mmap = itr->second;
-
- // check if we have this tile loaded
- uint32 packedGridPos = packTileID(x, y);
- if (mmap->mmapLoadedTiles.find(packedGridPos) == mmap->mmapLoadedTiles.end())
- {
- // file may not exist, therefore not loaded
- TC_LOG_DEBUG("maps", "MMAP:unloadMap: Asked to unload not loaded navmesh tile. %03u%02i%02i.mmtile", mapId, x, y);
- return false;
- }
-
- dtTileRef tileRef = mmap->mmapLoadedTiles[packedGridPos];
-
- // unload, and mark as non loaded
- if (dtStatusFailed(mmap->navMesh->removeTile(tileRef, NULL, NULL)))
- {
- // this is technically a memory leak
- // if the grid is later reloaded, dtNavMesh::addTile will return error but no extra memory is used
- // we cannot recover from this error - assert out
- TC_LOG_ERROR("maps", "MMAP:unloadMap: Could not unload %03u%02i%02i.mmtile from navmesh", mapId, x, y);
- ASSERT(false);
- }
- else
- {
- mmap->mmapLoadedTiles.erase(packedGridPos);
- --loadedTiles;
- TC_LOG_DEBUG("maps", "MMAP:unloadMap: Unloaded mmtile %03i[%02i, %02i] from %03i", mapId, x, y, mapId);
- return true;
- }
-
- return false;
- }
-
- bool MMapManager::unloadMap(uint32 mapId)
- {
- MMapDataSet::iterator itr = loadedMMaps.find(mapId);
- if (itr == loadedMMaps.end() || !itr->second)
- {
- // file may not exist, therefore not loaded
- TC_LOG_DEBUG("maps", "MMAP:unloadMap: Asked to unload not loaded navmesh map %03u", mapId);
- return false;
- }
-
- // unload all tiles from given map
- MMapData* mmap = itr->second;
- for (MMapTileSet::iterator i = mmap->mmapLoadedTiles.begin(); i != mmap->mmapLoadedTiles.end(); ++i)
- {
- uint32 x = (i->first >> 16);
- uint32 y = (i->first & 0x0000FFFF);
- if (dtStatusFailed(mmap->navMesh->removeTile(i->second, NULL, NULL)))
- TC_LOG_ERROR("maps", "MMAP:unloadMap: Could not unload %03u%02i%02i.mmtile from navmesh", mapId, x, y);
- else
- {
- --loadedTiles;
- TC_LOG_DEBUG("maps", "MMAP:unloadMap: Unloaded mmtile %03i[%02i, %02i] from %03i", mapId, x, y, mapId);
- }
- }
-
- delete mmap;
- itr->second = nullptr;
- TC_LOG_DEBUG("maps", "MMAP:unloadMap: Unloaded %03i.mmap", mapId);
-
- return true;
- }
-
- bool MMapManager::unloadMapInstance(uint32 mapId, uint32 instanceId)
- {
- // check if we have this map loaded
- MMapDataSet::const_iterator itr = GetMMapData(mapId);
- if (itr == loadedMMaps.end())
- {
- // file may not exist, therefore not loaded
- TC_LOG_DEBUG("maps", "MMAP:unloadMapInstance: Asked to unload not loaded navmesh map %03u", mapId);
- return false;
- }
-
- MMapData* mmap = itr->second;
- if (mmap->navMeshQueries.find(instanceId) == mmap->navMeshQueries.end())
- {
- TC_LOG_DEBUG("maps", "MMAP:unloadMapInstance: Asked to unload not loaded dtNavMeshQuery mapId %03u instanceId %u", mapId, instanceId);
- return false;
- }
-
- dtNavMeshQuery* query = mmap->navMeshQueries[instanceId];
-
- dtFreeNavMeshQuery(query);
- mmap->navMeshQueries.erase(instanceId);
- TC_LOG_DEBUG("maps", "MMAP:unloadMapInstance: Unloaded mapId %03u instanceId %u", mapId, instanceId);
-
- return true;
- }
-
- dtNavMesh const* MMapManager::GetNavMesh(uint32 mapId)
- {
- MMapDataSet::const_iterator itr = GetMMapData(mapId);
- if (itr == loadedMMaps.end())
- return NULL;
-
- return itr->second->navMesh;
- }
-
- dtNavMeshQuery const* MMapManager::GetNavMeshQuery(uint32 mapId, uint32 instanceId)
- {
- MMapDataSet::const_iterator itr = GetMMapData(mapId);
- if (itr == loadedMMaps.end())
- return NULL;
-
- MMapData* mmap = itr->second;
- if (mmap->navMeshQueries.find(instanceId) == mmap->navMeshQueries.end())
- {
- // allocate mesh query
- dtNavMeshQuery* query = dtAllocNavMeshQuery();
- ASSERT(query);
- if (dtStatusFailed(query->init(mmap->navMesh, 1024)))
- {
- dtFreeNavMeshQuery(query);
- TC_LOG_ERROR("maps", "MMAP:GetNavMeshQuery: Failed to initialize dtNavMeshQuery for mapId %03u instanceId %u", mapId, instanceId);
- return NULL;
- }
-
- TC_LOG_DEBUG("maps", "MMAP:GetNavMeshQuery: created dtNavMeshQuery for mapId %03u instanceId %u", mapId, instanceId);
- mmap->navMeshQueries.insert(std::pair<uint32, dtNavMeshQuery*>(instanceId, query));
- }
-
- return mmap->navMeshQueries[instanceId];
- }
-}
diff --git a/src/server/collision/Management/MMapManager.h b/src/server/collision/Management/MMapManager.h
deleted file mode 100644
index 42292b76942..00000000000
--- a/src/server/collision/Management/MMapManager.h
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * Copyright (C) 2008-2015 TrinityCore <http://www.trinitycore.org/>
- * 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, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef _MMAP_MANAGER_H
-#define _MMAP_MANAGER_H
-
-#include "Define.h"
-#include "DetourNavMesh.h"
-#include "DetourNavMeshQuery.h"
-
-#include <string>
-#include <unordered_map>
-#include <vector>
-
-// move map related classes
-namespace MMAP
-{
- typedef std::unordered_map<uint32, dtTileRef> MMapTileSet;
- typedef std::unordered_map<uint32, dtNavMeshQuery*> NavMeshQuerySet;
-
- // dummy struct to hold map's mmap data
- struct MMapData
- {
- MMapData(dtNavMesh* mesh) : navMesh(mesh) { }
- ~MMapData()
- {
- for (NavMeshQuerySet::iterator i = navMeshQueries.begin(); i != navMeshQueries.end(); ++i)
- dtFreeNavMeshQuery(i->second);
-
- if (navMesh)
- dtFreeNavMesh(navMesh);
- }
-
- dtNavMesh* navMesh;
-
- // we have to use single dtNavMeshQuery for every instance, since those are not thread safe
- NavMeshQuerySet navMeshQueries; // instanceId to query
- MMapTileSet mmapLoadedTiles; // maps [map grid coords] to [dtTile]
- };
-
-
- typedef std::unordered_map<uint32, MMapData*> MMapDataSet;
-
- // singleton class
- // holds all all access to mmap loading unloading and meshes
- class MMapManager
- {
- public:
- MMapManager() : loadedTiles(0), thread_safe_environment(true) {}
- ~MMapManager();
-
- void InitializeThreadUnsafe(const std::vector<uint32>& mapIds);
- bool loadMap(const std::string& basePath, uint32 mapId, int32 x, int32 y);
- bool unloadMap(uint32 mapId, int32 x, int32 y);
- bool unloadMap(uint32 mapId);
- bool unloadMapInstance(uint32 mapId, uint32 instanceId);
-
- // the returned [dtNavMeshQuery const*] is NOT threadsafe
- dtNavMeshQuery const* GetNavMeshQuery(uint32 mapId, uint32 instanceId);
- dtNavMesh const* GetNavMesh(uint32 mapId);
-
- uint32 getLoadedTilesCount() const { return loadedTiles; }
- uint32 getLoadedMapsCount() const { return loadedMMaps.size(); }
- private:
- bool loadMapData(uint32 mapId);
- uint32 packTileID(int32 x, int32 y);
-
- MMapDataSet::const_iterator GetMMapData(uint32 mapId) const;
- MMapDataSet loadedMMaps;
- uint32 loadedTiles;
- bool thread_safe_environment;
- };
-}
-
-#endif \ No newline at end of file
diff --git a/src/server/collision/Management/VMapFactory.cpp b/src/server/collision/Management/VMapFactory.cpp
deleted file mode 100644
index 4c2750a9e5c..00000000000
--- a/src/server/collision/Management/VMapFactory.cpp
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Copyright (C) 2008-2015 TrinityCore <http://www.trinitycore.org/>
- * 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, see <http://www.gnu.org/licenses/>.
- */
-
-#include "VMapFactory.h"
-#include "VMapManager2.h"
-
-namespace VMAP
-{
- IVMapManager* gVMapManager = NULL;
-
- //===============================================
- // just return the instance
- IVMapManager* VMapFactory::createOrGetVMapManager()
- {
- if (gVMapManager == nullptr)
- gVMapManager= new VMapManager2(); // should be taken from config ... Please change if you like :-)
- return gVMapManager;
- }
-
- //===============================================
- // delete all internal data structures
- void VMapFactory::clear()
- {
- delete gVMapManager;
- gVMapManager = NULL;
- }
-}
diff --git a/src/server/collision/Management/VMapFactory.h b/src/server/collision/Management/VMapFactory.h
deleted file mode 100644
index 3067c2919d5..00000000000
--- a/src/server/collision/Management/VMapFactory.h
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright (C) 2008-2015 TrinityCore <http://www.trinitycore.org/>
- * 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, see <http://www.gnu.org/licenses/>.
- */
-
-#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();
- };
-
-}
-#endif
diff --git a/src/server/collision/Management/VMapManager2.cpp b/src/server/collision/Management/VMapManager2.cpp
deleted file mode 100644
index 9594951196f..00000000000
--- a/src/server/collision/Management/VMapManager2.cpp
+++ /dev/null
@@ -1,329 +0,0 @@
-/*
- * Copyright (C) 2008-2015 TrinityCore <http://www.trinitycore.org/>
- * 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, see <http://www.gnu.org/licenses/>.
- */
-
-#include <iostream>
-#include <iomanip>
-#include <string>
-#include <sstream>
-#include "VMapManager2.h"
-#include "MapTree.h"
-#include "ModelInstance.h"
-#include "WorldModel.h"
-#include <G3D/Vector3.h>
-#include "Log.h"
-#include "VMapDefinitions.h"
-#include "Errors.h"
-
-using G3D::Vector3;
-
-namespace VMAP
-{
- VMapManager2::VMapManager2()
- {
- GetLiquidFlagsPtr = &GetLiquidFlagsDummy;
- IsVMAPDisabledForPtr = &IsVMAPDisabledForDummy;
- thread_safe_environment = true;
- }
-
- 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();
- }
- }
-
- void VMapManager2::InitializeThreadUnsafe(const std::vector<uint32>& mapIds)
- {
- // the caller must pass the list of all mapIds that will be used in the VMapManager2 lifetime
- for (const uint32& mapId : mapIds)
- iInstanceMapTrees.insert(InstanceTreeMap::value_type(mapId, nullptr));
-
- thread_safe_environment = false;
- }
-
- Vector3 VMapManager2::convertPositionToInternalRep(float x, float y, float z) const
- {
- Vector3 pos;
- const float mid = 0.5f * 64.0f * 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 mapId)
- {
- std::stringstream fname;
- fname.width(3);
- fname << std::setfill('0') << mapId << std::string(MAP_FILENAME_EXTENSION2);
-
- return fname.str();
- }
-
- int VMapManager2::loadMap(const char* basePath, unsigned int mapId, int x, int y)
- {
- int result = VMAP_LOAD_RESULT_IGNORED;
- if (isMapLoadingEnabled())
- {
- if (_loadMap(mapId, basePath, x, y))
- result = VMAP_LOAD_RESULT_OK;
- else
- result = VMAP_LOAD_RESULT_ERROR;
- }
-
- return result;
- }
-
- InstanceTreeMap::const_iterator VMapManager2::GetMapTree(uint32 mapId) const
- {
- // return the iterator if found or end() if not found/NULL
- InstanceTreeMap::const_iterator itr = iInstanceMapTrees.find(mapId);
- if (itr != iInstanceMapTrees.cend() && !itr->second)
- itr = iInstanceMapTrees.cend();
-
- return itr;
- }
-
- // load one tile (internal use only)
- bool VMapManager2::_loadMap(uint32 mapId, const std::string& basePath, uint32 tileX, uint32 tileY)
- {
- InstanceTreeMap::iterator instanceTree = iInstanceMapTrees.find(mapId);
- if (instanceTree == iInstanceMapTrees.end())
- {
- if (thread_safe_environment)
- instanceTree = iInstanceMapTrees.insert(InstanceTreeMap::value_type(mapId, nullptr)).first;
- else
- ASSERT(false, "Invalid mapId %u tile [%u, %u] passed to VMapManager2 after startup in thread unsafe environment",
- mapId, tileX, tileY);
- }
-
- if (!instanceTree->second)
- {
- std::string mapFileName = getMapFileName(mapId);
- StaticMapTree* newTree = new StaticMapTree(mapId, basePath);
- if (!newTree->InitMap(mapFileName, this))
- {
- delete newTree;
- return false;
- }
- instanceTree->second = newTree;
- }
-
- return instanceTree->second->LoadMapTile(tileX, tileY, this);
- }
-
- void VMapManager2::unloadMap(unsigned int mapId)
- {
- InstanceTreeMap::iterator instanceTree = iInstanceMapTrees.find(mapId);
- if (instanceTree != iInstanceMapTrees.end() && instanceTree->second)
- {
- instanceTree->second->UnloadMap(this);
- if (instanceTree->second->numLoadedTiles() == 0)
- {
- delete instanceTree->second;
- instanceTree->second = nullptr;
- }
- }
- }
-
- void VMapManager2::unloadMap(unsigned int mapId, int x, int y)
- {
- InstanceTreeMap::iterator instanceTree = iInstanceMapTrees.find(mapId);
- if (instanceTree != iInstanceMapTrees.end() && instanceTree->second)
- {
- instanceTree->second->UnloadMapTile(x, y, this);
- if (instanceTree->second->numLoadedTiles() == 0)
- {
- delete instanceTree->second;
- instanceTree->second = nullptr;
- }
- }
- }
-
- bool VMapManager2::isInLineOfSight(unsigned int mapId, float x1, float y1, float z1, float x2, float y2, float z2)
- {
- if (!isLineOfSightCalcEnabled() || IsVMAPDisabledForPtr(mapId, VMAP_DISABLE_LOS))
- return true;
-
- InstanceTreeMap::const_iterator instanceTree = GetMapTree(mapId);
- if (instanceTree != iInstanceMapTrees.end())
- {
- Vector3 pos1 = convertPositionToInternalRep(x1, y1, z1);
- Vector3 pos2 = convertPositionToInternalRep(x2, y2, z2);
- if (pos1 != pos2)
- {
- return instanceTree->second->isInLineOfSight(pos1, pos2);
- }
- }
-
- return true;
- }
-
- /**
- 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 mapId, float x1, float y1, float z1, float x2, float y2, float z2, float& rx, float &ry, float& rz, float modifyDist)
- {
- if (isLineOfSightCalcEnabled() && !IsVMAPDisabledForPtr(mapId, VMAP_DISABLE_LOS))
- {
- InstanceTreeMap::const_iterator instanceTree = GetMapTree(mapId);
- if (instanceTree != iInstanceMapTrees.end())
- {
- Vector3 pos1 = convertPositionToInternalRep(x1, y1, z1);
- Vector3 pos2 = convertPositionToInternalRep(x2, y2, z2);
- Vector3 resultPos;
- bool result = instanceTree->second->getObjectHitPos(pos1, pos2, resultPos, modifyDist);
- resultPos = convertPositionToInternalRep(resultPos.x, resultPos.y, resultPos.z);
- rx = resultPos.x;
- ry = resultPos.y;
- rz = resultPos.z;
- return result;
- }
- }
-
- rx = x2;
- ry = y2;
- rz = z2;
-
- return false;
- }
-
- /**
- get height or INVALID_HEIGHT if no height available
- */
-
- float VMapManager2::getHeight(unsigned int mapId, float x, float y, float z, float maxSearchDist)
- {
- if (isHeightCalcEnabled() && !IsVMAPDisabledForPtr(mapId, VMAP_DISABLE_HEIGHT))
- {
- InstanceTreeMap::const_iterator instanceTree = GetMapTree(mapId);
- if (instanceTree != iInstanceMapTrees.end())
- {
- Vector3 pos = convertPositionToInternalRep(x, y, z);
- float height = instanceTree->second->getHeight(pos, maxSearchDist);
- if (!(height < G3D::finf()))
- return height = VMAP_INVALID_HEIGHT_VALUE; // No height
-
- return height;
- }
- }
-
- return VMAP_INVALID_HEIGHT_VALUE;
- }
-
- bool VMapManager2::getAreaInfo(unsigned int mapId, float x, float y, float& z, uint32& flags, int32& adtId, int32& rootId, int32& groupId) const
- {
- if (!IsVMAPDisabledForPtr(mapId, VMAP_DISABLE_AREAFLAG))
- {
- InstanceTreeMap::const_iterator instanceTree = GetMapTree(mapId);
- if (instanceTree != iInstanceMapTrees.end())
- {
- Vector3 pos = convertPositionToInternalRep(x, y, z);
- bool result = instanceTree->second->getAreaInfo(pos, flags, adtId, rootId, groupId);
- // z is not touched by convertPositionToInternalRep(), so just copy
- z = pos.z;
- return result;
- }
- }
-
- return false;
- }
-
- bool VMapManager2::GetLiquidLevel(uint32 mapId, float x, float y, float z, uint8 reqLiquidType, float& level, float& floor, uint32& type) const
- {
- if (!IsVMAPDisabledForPtr(mapId, VMAP_DISABLE_LIQUIDSTATUS))
- {
- InstanceTreeMap::const_iterator instanceTree = GetMapTree(mapId);
- if (instanceTree != iInstanceMapTrees.end())
- {
- LocationInfo info;
- Vector3 pos = convertPositionToInternalRep(x, y, z);
- if (instanceTree->second->GetLocationInfo(pos, info))
- {
- floor = info.ground_Z;
- ASSERT(floor < std::numeric_limits<float>::max());
- ASSERT(info.hitModel);
- type = info.hitModel->GetLiquidType(); // entry from LiquidType.dbc
- if (reqLiquidType && !(GetLiquidFlagsPtr(type) & reqLiquidType))
- return false;
- ASSERT(info.hitInstance);
- if (info.hitInstance->GetLiquidLevel(pos, info, level))
- return true;
- }
- }
- }
-
- return false;
- }
-
- WorldModel* VMapManager2::acquireModelInstance(const std::string& basepath, const std::string& filename)
- {
- //! Critical section, thread safe access to iLoadedModelFiles
- std::lock_guard<std::mutex> lock(LoadedModelFilesLock);
-
- ModelFileMap::iterator model = iLoadedModelFiles.find(filename);
- if (model == iLoadedModelFiles.end())
- {
- WorldModel* worldmodel = new WorldModel();
- if (!worldmodel->readFile(basepath + filename + ".vmo"))
- {
- VMAP_ERROR_LOG("misc", "VMapManager2: could not load '%s%s.vmo'", basepath.c_str(), filename.c_str());
- delete worldmodel;
- return NULL;
- }
- VMAP_DEBUG_LOG("maps", "VMapManager2: loading file '%s%s'", basepath.c_str(), filename.c_str());
- 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)
- {
- //! Critical section, thread safe access to iLoadedModelFiles
- std::lock_guard<std::mutex> lock(LoadedModelFilesLock);
-
- ModelFileMap::iterator model = iLoadedModelFiles.find(filename);
- if (model == iLoadedModelFiles.end())
- {
- VMAP_ERROR_LOG("misc", "VMapManager2: trying to unload non-loaded file '%s'", filename.c_str());
- return;
- }
- if (model->second.decRefCount() == 0)
- {
- VMAP_DEBUG_LOG("maps", "VMapManager2: unloading file '%s'", filename.c_str());
- delete model->second.getModel();
- iLoadedModelFiles.erase(model);
- }
- }
-
- bool VMapManager2::existsMap(const char* basePath, unsigned int mapId, int x, int y)
- {
- return StaticMapTree::CanLoadMap(std::string(basePath), mapId, x, y);
- }
-
-} // namespace VMAP
diff --git a/src/server/collision/Management/VMapManager2.h b/src/server/collision/Management/VMapManager2.h
deleted file mode 100644
index a5891e9642b..00000000000
--- a/src/server/collision/Management/VMapManager2.h
+++ /dev/null
@@ -1,142 +0,0 @@
-/*
- * Copyright (C) 2008-2015 TrinityCore <http://www.trinitycore.org/>
- * 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, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef _VMAPMANAGER2_H
-#define _VMAPMANAGER2_H
-
-#include <mutex>
-#include <unordered_map>
-#include <vector>
-#include "Define.h"
-#include "IVMapManager.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 G3D
-{
- class Vector3;
-}
-
-namespace VMAP
-{
- class StaticMapTree;
- class WorldModel;
-
- class ManagedModel
- {
- public:
- ManagedModel() : iModel(nullptr), 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 std::unordered_map<uint32, StaticMapTree*> InstanceTreeMap;
- typedef std::unordered_map<std::string, ManagedModel> ModelFileMap;
-
- enum DisableTypes
- {
- VMAP_DISABLE_AREAFLAG = 0x1,
- VMAP_DISABLE_HEIGHT = 0x2,
- VMAP_DISABLE_LOS = 0x4,
- VMAP_DISABLE_LIQUIDSTATUS = 0x8
- };
-
- class VMapManager2 : public IVMapManager
- {
- protected:
- // Tree to check collision
- ModelFileMap iLoadedModelFiles;
- InstanceTreeMap iInstanceMapTrees;
- bool thread_safe_environment;
- // Mutex for iLoadedModelFiles
- std::mutex LoadedModelFilesLock;
-
- bool _loadMap(uint32 mapId, const std::string& basePath, uint32 tileX, uint32 tileY);
- /* void _unloadMap(uint32 pMapId, uint32 x, uint32 y); */
-
- static uint32 GetLiquidFlagsDummy(uint32) { return 0; }
- static bool IsVMAPDisabledForDummy(uint32 /*entry*/, uint8 /*flags*/) { return false; }
-
- InstanceTreeMap::const_iterator GetMapTree(uint32 mapId) const;
-
- public:
- // public for debug
- G3D::Vector3 convertPositionToInternalRep(float x, float y, float z) const;
- static std::string getMapFileName(unsigned int mapId);
-
- VMapManager2();
- ~VMapManager2(void);
-
- void InitializeThreadUnsafe(const std::vector<uint32>& mapIds);
- int loadMap(const char* pBasePath, unsigned int mapId, int x, int y) override;
-
- void unloadMap(unsigned int mapId, int x, int y) override;
- void unloadMap(unsigned int mapId) override;
-
- bool isInLineOfSight(unsigned int mapId, float x1, float y1, float z1, float x2, float y2, float z2) override ;
- /**
- fill the hit pos and return true, if an object was hit
- */
- bool getObjectHitPos(unsigned int mapId, float x1, float y1, float z1, float x2, float y2, float z2, float& rx, float& ry, float& rz, float modifyDist) override;
- float getHeight(unsigned int mapId, float x, float y, float z, float maxSearchDist) override;
-
- bool processCommand(char* /*command*/) override { return false; } // for debug and extensions
-
- bool getAreaInfo(unsigned int pMapId, float x, float y, float& z, uint32& flags, int32& adtId, int32& rootId, int32& groupId) const override;
- bool GetLiquidLevel(uint32 pMapId, float x, float y, float z, uint8 reqLiquidType, float& level, float& floor, uint32& type) const override;
-
- 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 mapId, int /*x*/, int /*y*/) const override
- {
- return getMapFileName(mapId);
- }
- virtual bool existsMap(const char* basePath, unsigned int mapId, int x, int y) override;
- public:
- void getInstanceMapTree(InstanceTreeMap &instanceMapTree);
-
- typedef uint32(*GetLiquidFlagsFn)(uint32 liquidType);
- GetLiquidFlagsFn GetLiquidFlagsPtr;
-
- typedef bool(*IsVMAPDisabledForFn)(uint32 entry, uint8 flags);
- IsVMAPDisabledForFn IsVMAPDisabledForPtr;
- };
-}
-
-#endif
diff --git a/src/server/collision/Maps/MapTree.cpp b/src/server/collision/Maps/MapTree.cpp
deleted file mode 100644
index b493ec18f5f..00000000000
--- a/src/server/collision/Maps/MapTree.cpp
+++ /dev/null
@@ -1,477 +0,0 @@
-/*
- * Copyright (C) 2008-2015 TrinityCore <http://www.trinitycore.org/>
- * 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, see <http://www.gnu.org/licenses/>.
- */
-
-#include "MapTree.h"
-#include "ModelInstance.h"
-#include "VMapManager2.h"
-#include "VMapDefinitions.h"
-#include "Log.h"
-#include "Errors.h"
-
-#include <string>
-#include <sstream>
-#include <iomanip>
-#include <limits>
-
-using G3D::Vector3;
-
-namespace VMAP
-{
-
- class MapRayCallback
- {
- public:
- MapRayCallback(ModelInstance* val): prims(val), hit(false) { }
- bool operator()(const G3D::Ray& ray, uint32 entry, float& distance, bool pStopAtFirstHit=true)
- {
- bool result = prims[entry].intersectRay(ray, distance, pStopAtFirstHit);
- if (result)
- hit = true;
- return result;
- }
- bool didHit() { return hit; }
- protected:
- ModelInstance* prims;
- bool hit;
- };
-
- class AreaInfoCallback
- {
- public:
- AreaInfoCallback(ModelInstance* val): prims(val) { }
- void operator()(const Vector3& point, uint32 entry)
- {
-#ifdef VMAP_DEBUG
- TC_LOG_DEBUG("maps", "AreaInfoCallback: trying to intersect '%s'", prims[entry].name.c_str());
-#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
- TC_LOG_DEBUG("maps", "LocationInfoCallback: trying to intersect '%s'", prims[entry].name.c_str());
-#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), iIsTiled(false), iTreeValues(NULL),
- iNTreeValues(0), iBasePath(basePath)
- {
- if (iBasePath.length() > 0 && iBasePath[iBasePath.length()-1] != '/' && iBasePath[iBasePath.length()-1] != '\\')
- {
- iBasePath.push_back('/');
- }
- }
-
- //=========================================================
- //! Make sure to call unloadMap() to unregister acquired model references before destroying
- StaticMapTree::~StaticMapTree()
- {
- delete[] iTreeValues;
- }
-
- //=========================================================
- /**
- If intersection is found within pMaxDist, sets pMaxDist to intersection distance and returns true.
- Else, pMaxDist is not modified and returns false;
- */
-
- bool StaticMapTree::getIntersectionTime(const G3D::Ray& pRay, float &pMaxDist, bool pStopAtFirstHit) const
- {
- float distance = pMaxDist;
- MapRayCallback intersectionCallBack(iTreeValues);
- iTree.intersectRay(pRay, intersectionCallBack, distance, pStopAtFirstHit);
- if (intersectionCallBack.didHit())
- pMaxDist = distance;
- return intersectionCallBack.didHit();
- }
- //=========================================================
-
- bool StaticMapTree::isInLineOfSight(const Vector3& pos1, const Vector3& pos2) const
- {
- float maxDist = (pos2 - pos1).magnitude();
- // return false if distance is over max float, in case of cheater teleporting to the end of the universe
- if (maxDist == std::numeric_limits<float>::max() || !std::isfinite(maxDist))
- return false;
-
- // valid map coords should *never ever* produce float overflow, but this would produce NaNs too
- ASSERT(maxDist < std::numeric_limits<float>::max());
- // 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);
- if (getIntersectionTime(ray, maxDist, true))
- return false;
-
- return true;
- }
- //=========================================================
- /**
- 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();
- // valid map coords should *never ever* produce float overflow, but this would produce NaNs too
- ASSERT(maxDist < std::numeric_limits<float>::max());
- // 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 = maxDist;
- if (getIntersectionTime(ray, dist, false))
- {
- 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, float maxSearchDist) const
- {
- float height = G3D::finf();
- Vector3 dir = Vector3(0, 0, -1);
- G3D::Ray ray(pPos, dir); // direction with length of 1
- float maxDist = maxSearchDist;
- if (getIntersectionTime(ray, maxDist, false))
- {
- height = pPos.z - maxDist;
- }
- 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.push_back('/');
- 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
- {
- if (!readChunk(tf, chunk, VMAP_MAGIC, 8))
- success = false;
- fclose(tf);
- }
- }
- fclose(rf);
- return success;
- }
-
- //=========================================================
-
- bool StaticMapTree::InitMap(const std::string &fname, VMapManager2* vm)
- {
- VMAP_DEBUG_LOG("maps", "StaticMapTree::InitMap() : initializing StaticMapTree '%s'", fname.c_str());
- bool success = false;
- std::string fullname = iBasePath + fname;
- FILE* rf = fopen(fullname.c_str(), "rb");
- if (!rf)
- return false;
-
- char chunk[8];
- char tiled = '\0';
-
- if (readChunk(rf, chunk, VMAP_MAGIC, 8) && fread(&tiled, sizeof(char), 1, rf) == 1 &&
- readChunk(rf, chunk, "NODE", 4) && iTree.readFromFile(rf))
- {
- iNTreeValues = iTree.primCount();
- iTreeValues = new ModelInstance[iNTreeValues];
- success = readChunk(rf, chunk, "GOBJ", 4);
- }
-
- iIsTiled = tiled != '\0';
-
- // global model spawns
- // only non-tiled maps have them, and if so exactly one (so far at least...)
- ModelSpawn spawn;
-#ifdef VMAP_DEBUG
- TC_LOG_DEBUG("maps", "StaticMapTree::InitMap() : map isTiled: %u", static_cast<uint32>(iIsTiled));
-#endif
- if (!iIsTiled && ModelSpawn::readFromFile(rf, spawn))
- {
- WorldModel* model = vm->acquireModelInstance(iBasePath, spawn.name);
- VMAP_DEBUG_LOG("maps", "StaticMapTree::InitMap() : loading %s", spawn.name.c_str());
- 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;
- VMAP_ERROR_LOG("misc", "StaticMapTree::InitMap() : could not acquire WorldModel pointer for '%s'", spawn.name.c_str());
- }
- }
-
- 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)
- {
- VMAP_ERROR_LOG("misc", "StaticMapTree::LoadMapTile() : tree has not been initialized [%u, %u]", tileX, tileY);
- return false;
- }
- bool result = true;
-
- std::string tilefile = iBasePath + getTileFileName(iMapID, tileX, tileY);
- FILE* tf = fopen(tilefile.c_str(), "rb");
- if (tf)
- {
- char chunk[8];
-
- if (!readChunk(tf, chunk, VMAP_MAGIC, 8))
- result = false;
- uint32 numSpawns = 0;
- if (result && 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)
- VMAP_ERROR_LOG("misc", "StaticMapTree::LoadMapTile() : could not acquire WorldModel pointer [%u, %u]", tileX, tileY);
-
- // update tree
- uint32 referencedVal;
-
- if (fread(&referencedVal, sizeof(uint32), 1, tf) == 1)
- {
- if (!iLoadedSpawns.count(referencedVal))
- {
- if (referencedVal > iNTreeValues)
- {
- VMAP_ERROR_LOG("maps", "StaticMapTree::LoadMapTile() : invalid tree element (%u/%u) referenced in tile %s", referencedVal, iNTreeValues, tilefile.c_str());
- continue;
- }
-
- iTreeValues[referencedVal] = ModelInstance(spawn, model);
- iLoadedSpawns[referencedVal] = 1;
- }
- else
- {
- ++iLoadedSpawns[referencedVal];
-#ifdef VMAP_DEBUG
- if (iTreeValues[referencedVal].ID != spawn.ID)
- TC_LOG_DEBUG("maps", "StaticMapTree::LoadMapTile() : trying to load wrong spawn in node");
- else if (iTreeValues[referencedVal].name != spawn.name)
- TC_LOG_DEBUG("maps", "StaticMapTree::LoadMapTile() : name collision on GUID=%u", spawn.ID);
-#endif
- }
- }
- else
- result = false;
- }
- }
- 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())
- {
- VMAP_ERROR_LOG("misc", "StaticMapTree::UnloadMapTile() : trying to unload non-loaded tile - Map:%u X:%u Y:%u", iMapID, tileX, tileY);
- 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;
- char chunk[8];
- if (!readChunk(tf, chunk, VMAP_MAGIC, 8))
- result = false;
- 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;
-
- if (fread(&referencedNode, sizeof(uint32), 1, tf) != 1)
- result = false;
- else
- {
- if (!iLoadedSpawns.count(referencedNode))
- VMAP_ERROR_LOG("misc", "StaticMapTree::UnloadMapTile() : trying to unload non-referenced model '%s' (ID:%u)", spawn.name.c_str(), spawn.ID);
- else if (--iLoadedSpawns[referencedNode] == 0)
- {
- iTreeValues[referencedNode].setUnloaded();
- iLoadedSpawns.erase(referencedNode);
- }
- }
- }
- }
- fclose(tf);
- }
- }
- iLoadedTiles.erase(tile);
- }
-}
diff --git a/src/server/collision/Maps/MapTree.h b/src/server/collision/Maps/MapTree.h
deleted file mode 100644
index 08bd5c3d3a1..00000000000
--- a/src/server/collision/Maps/MapTree.h
+++ /dev/null
@@ -1,103 +0,0 @@
-/*
- * Copyright (C) 2008-2015 TrinityCore <http://www.trinitycore.org/>
- * 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, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef _MAPTREE_H
-#define _MAPTREE_H
-
-#include "Define.h"
-#include "BoundingIntervalHierarchy.h"
-#include <unordered_map>
-
-namespace VMAP
-{
- class ModelInstance;
- class GroupModel;
- class VMapManager2;
-
- struct LocationInfo
- {
- LocationInfo(): hitInstance(nullptr), hitModel(nullptr), ground_Z(-G3D::finf()) { }
- const ModelInstance* hitInstance;
- const GroupModel* hitModel;
- float ground_Z;
- };
-
- class StaticMapTree
- {
- typedef std::unordered_map<uint32, bool> loadedTileMap;
- typedef std::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:
- bool 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, float maxSearchDist) const;
- bool getAreaInfo(G3D::Vector3 &pos, uint32 &flags, int32 &adtId, int32 &rootId, int32 &groupId) const;
- bool GetLocationInfo(const G3D::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(); }
- void getModelInstances(ModelInstance* &models, uint32 &count);
-
- private:
- StaticMapTree(StaticMapTree const& right) = delete;
- StaticMapTree& operator=(StaticMapTree const& right) = delete;
- };
-
- struct AreaInfo
- {
- AreaInfo(): result(false), ground_Z(-G3D::finf()), flags(0), adtId(0),
- rootId(0), groupId(0) { }
- bool result;
- float ground_Z;
- uint32 flags;
- int32 adtId;
- int32 rootId;
- int32 groupId;
- };
-} // VMAP
-
-#endif // _MAPTREE_H
diff --git a/src/server/collision/Maps/TileAssembler.cpp b/src/server/collision/Maps/TileAssembler.cpp
deleted file mode 100644
index ec7b759f975..00000000000
--- a/src/server/collision/Maps/TileAssembler.cpp
+++ /dev/null
@@ -1,550 +0,0 @@
-/*
- * Copyright (C) 2008-2015 TrinityCore <http://www.trinitycore.org/>
- * 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, see <http://www.gnu.org/licenses/>.
- */
-
-#include "TileAssembler.h"
-#include "MapTree.h"
-#include "BoundingIntervalHierarchy.h"
-#include "VMapDefinitions.h"
-
-#include <set>
-#include <iomanip>
-#include <sstream>
-
-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)
- : iDestDir(pDestDirName), iSrcDir(pSrcDirName), iFilterMethod(NULL), iCurrentUniqueNameId(0)
- {
- //mkdir(iDestDir);
- //init();
- }
-
- TileAssembler::~TileAssembler()
- {
- //delete iCoordModelMapping;
- }
-
- bool TileAssembler::convertWorld2()
- {
- 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;
- printf("Calculating model bounds for map %u...\n", map_iter->first);
- 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);
- }
-
- printf("Creating map tree for map %u...\n", map_iter->first);
- BIH pTree;
-
- try
- {
- pTree.build(mapSpawns, BoundsTrait<ModelSpawn*>::getBounds);
- }
- catch (std::exception& e)
- {
- printf("Exception ""%s"" when calling pTree.build", e.what());
- return false;
- }
-
- // ===> 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));
-
- // 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";
- if (FILE* tilefile = fopen(tilefilename.str().c_str(), "wb"))
- {
- // file header
- if (success && fwrite(VMAP_MAGIC, 1, 8, tilefile) != 8) success = false;
- // 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
- }
-
- // add an object models, listed in temp_gameobject_models file
- exportGameobjectModels();
- // 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 %u\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);
- modelFilename.push_back('/');
- modelFilename.append(spawn.name);
-
- ModelPosition modelPosition;
- modelPosition.iDir = spawn.iRot;
- modelPosition.iScale = spawn.iScale;
- modelPosition.init();
-
- WorldModel_Raw raw_model;
- if (!raw_model.Read(modelFilename.c_str()))
- return false;
-
- uint32 groups = raw_model.groupsArray.size();
- if (groups != 1)
- printf("Warning: '%s' does not seem to be a M2 model!\n", modelFilename.c_str());
-
- AABox modelBound;
- bool boundEmpty=true;
-
- for (uint32 g=0; g<groups; ++g) // should be only one for M2 files...
- {
- std::vector<Vector3>& vertices = raw_model.groupsArray[g].vertexArray;
-
- if (vertices.empty())
- {
- std::cout << "error: model '" << spawn.name << "' has no geometry!" << std::endl;
- continue;
- }
-
- uint32 nvectors = vertices.size();
- for (uint32 i = 0; i < nvectors; ++i)
- {
- Vector3 v = modelPosition.transform(vertices[i]);
-
- if (boundEmpty)
- modelBound = AABox(v, v), boundEmpty=false;
- else
- modelBound.merge(v);
- }
- }
- spawn.iBound = modelBound + spawn.iPos;
- spawn.flags |= MOD_HAS_BOUND;
- 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.push_back('/');
- filename.append(pModelFilename);
-
- WorldModel_Raw raw_model;
- if (!raw_model.Read(filename.c_str()))
- return false;
-
- // write WorldModel
- WorldModel model;
- model.setRootWmoID(raw_model.RootWMOID);
- if (!raw_model.groupsArray.empty())
- {
- std::vector<GroupModel> groupsArray;
-
- uint32 groups = raw_model.groupsArray.size();
- for (uint32 g = 0; g < groups; ++g)
- {
- GroupModel_Raw& raw_group = raw_model.groupsArray[g];
- groupsArray.push_back(GroupModel(raw_group.mogpflags, raw_group.GroupWMOID, raw_group.bounds ));
- groupsArray.back().setMeshData(raw_group.vertexArray, raw_group.triangles);
- groupsArray.back().setLiquidData(raw_group.liquid);
- }
-
- model.setGroupModels(groupsArray);
- }
-
- success = model.writeFile(iDestDir + "/" + pModelFilename + ".vmo");
- //std::cout << "readRawFile2: '" << pModelFilename << "' tris: " << nElements << " nodes: " << nNodes << std::endl;
- return success;
- }
-
- void TileAssembler::exportGameobjectModels()
- {
- FILE* model_list = fopen((iSrcDir + "/" + "temp_gameobject_models").c_str(), "rb");
- if (!model_list)
- return;
-
- FILE* model_list_copy = fopen((iDestDir + "/" + GAMEOBJECT_MODELS).c_str(), "wb");
- if (!model_list_copy)
- {
- fclose(model_list);
- return;
- }
-
- uint32 name_length, displayId;
- char buff[500];
- while (!feof(model_list))
- {
- if (fread(&displayId, sizeof(uint32), 1, model_list) != 1
- || fread(&name_length, sizeof(uint32), 1, model_list) != 1
- || name_length >= sizeof(buff)
- || fread(&buff, sizeof(char), name_length, model_list) != name_length)
- {
- std::cout << "\nFile 'temp_gameobject_models' seems to be corrupted" << std::endl;
- break;
- }
-
- std::string model_name(buff, name_length);
-
- WorldModel_Raw raw_model;
- if ( !raw_model.Read((iSrcDir + "/" + model_name).c_str()) )
- continue;
-
- spawnedModelFiles.insert(model_name);
- AABox bounds;
- bool boundEmpty = true;
- for (uint32 g = 0; g < raw_model.groupsArray.size(); ++g)
- {
- std::vector<Vector3>& vertices = raw_model.groupsArray[g].vertexArray;
-
- uint32 nvectors = vertices.size();
- for (uint32 i = 0; i < nvectors; ++i)
- {
- Vector3& v = vertices[i];
- if (boundEmpty)
- bounds = AABox(v, v), boundEmpty = false;
- else
- bounds.merge(v);
- }
- }
-
- if (bounds.isEmpty())
- {
- std::cout << "\nModel " << std::string(buff, name_length) << " has empty bounding box" << std::endl;
- continue;
- }
-
- if (!bounds.isFinite())
- {
- std::cout << "\nModel " << std::string(buff, name_length) << " has invalid bounding box" << std::endl;
- continue;
- }
-
- fwrite(&displayId, sizeof(uint32), 1, model_list_copy);
- fwrite(&name_length, sizeof(uint32), 1, model_list_copy);
- fwrite(&buff, sizeof(char), name_length, model_list_copy);
- fwrite(&bounds.low(), sizeof(Vector3), 1, model_list_copy);
- fwrite(&bounds.high(), sizeof(Vector3), 1, model_list_copy);
- }
-
- fclose(model_list);
- fclose(model_list_copy);
- }
- // 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); }
- #define READ_OR_RETURN_WITH_DELETE(V, S) if (fread((V), (S), 1, rf) != 1) { \
- fclose(rf); printf("readfail, op = %i\n", readOperation); delete[] V; return(false); };
- #define CMP_OR_RETURN(V, S) if (strcmp((V), (S)) != 0) { \
- fclose(rf); printf("cmpfail, %s!=%s\n", V, S);return(false); }
-
- bool GroupModel_Raw::Read(FILE* rf)
- {
- char blockId[5];
- blockId[4] = 0;
- int blocksize;
- int readOperation = 0;
-
- READ_OR_RETURN(&mogpflags, sizeof(uint32));
- READ_OR_RETURN(&GroupWMOID, sizeof(uint32));
-
-
- Vector3 vec1, vec2;
- READ_OR_RETURN(&vec1, sizeof(Vector3));
-
- READ_OR_RETURN(&vec2, sizeof(Vector3));
- bounds.set(vec1, vec2);
-
- 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_WITH_DELETE(indexarray, nindexes*sizeof(uint16));
- triangles.reserve(nindexes / 3);
- 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_WITH_DELETE(vectorarray, nvectors*sizeof(float)*3);
- for (uint32 i=0; i<nvectors; ++i)
- vertexArray.push_back( Vector3(vectorarray + 3*i) );
-
- delete[] vectorarray;
- }
- // ----- liquid
- 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);
- }
-
- return true;
- }
-
-
- GroupModel_Raw::~GroupModel_Raw()
- {
- delete liquid;
- }
-
- bool WorldModel_Raw::Read(const char * path)
- {
- FILE* rf = fopen(path, "rb");
- if (!rf)
- {
- printf("ERROR: Can't open raw model file: %s\n", path);
- return false;
- }
-
- char ident[9];
- ident[8] = '\0';
- int readOperation = 0;
-
- READ_OR_RETURN(&ident, 8);
- CMP_OR_RETURN(ident, RAW_VMAP_MAGIC);
-
- // 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;
- READ_OR_RETURN(&groups, sizeof(uint32));
- READ_OR_RETURN(&RootWMOID, sizeof(uint32));
-
- groupsArray.resize(groups);
- bool succeed = true;
- for (uint32 g = 0; g < groups && succeed; ++g)
- succeed = groupsArray[g].Read(rf);
-
- if (succeed) /// rf will be freed inside Read if the function had any errors.
- fclose(rf);
- return succeed;
- }
-
- // drop of temporary use defines
- #undef READ_OR_RETURN
- #undef CMP_OR_RETURN
-}
diff --git a/src/server/collision/Maps/TileAssembler.h b/src/server/collision/Maps/TileAssembler.h
deleted file mode 100644
index 581622c6b73..00000000000
--- a/src/server/collision/Maps/TileAssembler.h
+++ /dev/null
@@ -1,119 +0,0 @@
-/*
- * Copyright (C) 2008-2015 TrinityCore <http://www.trinitycore.org/>
- * 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, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef _TILEASSEMBLER_H_
-#define _TILEASSEMBLER_H_
-
-#include <G3D/Vector3.h>
-#include <G3D/Matrix3.h>
-#include <map>
-#include <set>
-
-#include "ModelInstance.h"
-#include "WorldModel.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:
- ModelPosition(): iScale(0.0f) { }
- G3D::Vector3 iPos;
- G3D::Vector3 iDir;
- float iScale;
- void init()
- {
- iRotation = G3D::Matrix3::fromEulerAnglesZYX(G3D::pif()*iDir.y/180.f, G3D::pif()*iDir.x/180.f, G3D::pif()*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;
- //===============================================
-
- struct GroupModel_Raw
- {
- uint32 mogpflags;
- uint32 GroupWMOID;
-
- G3D::AABox bounds;
- uint32 liquidflags;
- std::vector<MeshTriangle> triangles;
- std::vector<G3D::Vector3> vertexArray;
- class WmoLiquid* liquid;
-
- GroupModel_Raw() : mogpflags(0), GroupWMOID(0), liquidflags(0),
- liquid(NULL) { }
- ~GroupModel_Raw();
-
- bool Read(FILE* f);
- };
-
- struct WorldModel_Raw
- {
- uint32 RootWMOID;
- std::vector<GroupModel_Raw> groupsArray;
-
- bool Read(const char * path);
- };
-
- 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;
- std::set<std::string> spawnedModelFiles;
-
- public:
- TileAssembler(const std::string& pSrcDirName, const std::string& pDestDirName);
- virtual ~TileAssembler();
-
- bool convertWorld2();
- bool readMapSpawns();
- bool calculateTransformedBound(ModelSpawn &spawn);
- void exportGameobjectModels();
-
- bool convertRawFile(const std::string& pModelFilename);
- void setModelNameFilterMethod(bool (*pFilterMethod)(char *pName)) { iFilterMethod = pFilterMethod; }
- std::string getDirEntryNameFromModName(unsigned int pMapId, const std::string& pModPosName);
- };
-
-} // VMAP
-#endif /*_TILEASSEMBLER_H_*/
diff --git a/src/server/collision/Models/GameObjectModel.cpp b/src/server/collision/Models/GameObjectModel.cpp
deleted file mode 100644
index dbdc0554e06..00000000000
--- a/src/server/collision/Models/GameObjectModel.cpp
+++ /dev/null
@@ -1,216 +0,0 @@
-/*
- * Copyright (C) 2008-2015 TrinityCore <http://www.trinitycore.org/>
- * 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, see <http://www.gnu.org/licenses/>.
- */
-
-#include "VMapFactory.h"
-#include "VMapManager2.h"
-#include "VMapDefinitions.h"
-#include "WorldModel.h"
-#include "GameObjectModel.h"
-#include "Log.h"
-#include "Timer.h"
-
-using G3D::Vector3;
-using G3D::Ray;
-using G3D::AABox;
-
-struct GameobjectModelData
-{
- GameobjectModelData(const std::string& name_, const AABox& box) :
- bound(box), name(name_) { }
-
- AABox bound;
- std::string name;
-};
-
-typedef std::unordered_map<uint32, GameobjectModelData> ModelList;
-ModelList model_list;
-
-void LoadGameObjectModelList(std::string const& dataPath)
-{
-#ifndef NO_CORE_FUNCS
- uint32 oldMSTime = getMSTime();
-#endif
-
- FILE* model_list_file = fopen((dataPath + "vmaps/" + VMAP::GAMEOBJECT_MODELS).c_str(), "rb");
- if (!model_list_file)
- {
- VMAP_ERROR_LOG("misc", "Unable to open '%s' file.", VMAP::GAMEOBJECT_MODELS);
- return;
- }
-
- uint32 name_length, displayId;
- char buff[500];
- while (true)
- {
- Vector3 v1, v2;
- if (fread(&displayId, sizeof(uint32), 1, model_list_file) != 1)
- if (feof(model_list_file)) // EOF flag is only set after failed reading attempt
- break;
-
- if (fread(&name_length, sizeof(uint32), 1, model_list_file) != 1
- || name_length >= sizeof(buff)
- || fread(&buff, sizeof(char), name_length, model_list_file) != name_length
- || fread(&v1, sizeof(Vector3), 1, model_list_file) != 1
- || fread(&v2, sizeof(Vector3), 1, model_list_file) != 1)
- {
- VMAP_ERROR_LOG("misc", "File '%s' seems to be corrupted!", VMAP::GAMEOBJECT_MODELS);
- break;
- }
-
- if (v1.isNaN() || v2.isNaN())
- {
- VMAP_ERROR_LOG("misc", "File '%s' Model '%s' has invalid v1%s v2%s values!", VMAP::GAMEOBJECT_MODELS, std::string(buff, name_length).c_str(), v1.toString().c_str(), v2.toString().c_str());
- continue;
- }
-
- model_list.insert
- (
- ModelList::value_type(displayId, GameobjectModelData(std::string(buff, name_length), AABox(v1, v2)))
- );
- }
-
- fclose(model_list_file);
- VMAP_INFO_LOG("server.loading", ">> Loaded %u GameObject models in %u ms", uint32(model_list.size()), GetMSTimeDiffToNow(oldMSTime));
-}
-
-GameObjectModel::~GameObjectModel()
-{
- if (iModel)
- ((VMAP::VMapManager2*)VMAP::VMapFactory::createOrGetVMapManager())->releaseModelInstance(name);
-}
-
-bool GameObjectModel::initialize(std::unique_ptr<GameObjectModelOwnerBase> modelOwner, std::string const& dataPath)
-{
- ModelList::const_iterator it = model_list.find(modelOwner->GetDisplayId());
- if (it == model_list.end())
- return false;
-
- G3D::AABox mdl_box(it->second.bound);
- // ignore models with no bounds
- if (mdl_box == G3D::AABox::zero())
- {
- VMAP_ERROR_LOG("misc", "GameObject model %s has zero bounds, loading skipped", it->second.name.c_str());
- return false;
- }
-
- iModel = ((VMAP::VMapManager2*)VMAP::VMapFactory::createOrGetVMapManager())->acquireModelInstance(dataPath + "vmaps/", it->second.name);
-
- if (!iModel)
- return false;
-
- name = it->second.name;
- iPos = modelOwner->GetPosition();
- phasemask = modelOwner->GetPhaseMask();
- iScale = modelOwner->GetScale();
- iInvScale = 1.f / iScale;
-
- G3D::Matrix3 iRotation = G3D::Matrix3::fromEulerAnglesZYX(modelOwner->GetOrientation(), 0, 0);
- iInvRot = iRotation.inverse();
- // transform bounding box:
- mdl_box = AABox(mdl_box.low() * iScale, mdl_box.high() * iScale);
- AABox rotated_bounds;
- for (int i = 0; i < 8; ++i)
- rotated_bounds.merge(iRotation * mdl_box.corner(i));
-
- iBound = rotated_bounds + iPos;
-#ifdef SPAWN_CORNERS
- // test:
- for (int i = 0; i < 8; ++i)
- {
- Vector3 pos(iBound.corner(i));
- modelOwner->DebugVisualizeCorner(pos);
- }
-#endif
-
- owner = std::move(modelOwner);
- return true;
-}
-
-GameObjectModel* GameObjectModel::Create(std::unique_ptr<GameObjectModelOwnerBase> modelOwner, std::string const& dataPath)
-{
- GameObjectModel* mdl = new GameObjectModel();
- if (!mdl->initialize(std::move(modelOwner), dataPath))
- {
- delete mdl;
- return NULL;
- }
-
- return mdl;
-}
-
-bool GameObjectModel::intersectRay(const G3D::Ray& ray, float& MaxDist, bool StopAtFirstHit, uint32 ph_mask) const
-{
- if (!(phasemask & ph_mask) || !owner->IsSpawned())
- return false;
-
- float time = ray.intersectionTime(iBound);
- if (time == G3D::finf())
- return false;
-
- // child bounds are defined in object space:
- Vector3 p = iInvRot * (ray.origin() - iPos) * iInvScale;
- Ray modRay(p, iInvRot * ray.direction());
- float distance = MaxDist * iInvScale;
- bool hit = iModel->IntersectRay(modRay, distance, StopAtFirstHit);
- if (hit)
- {
- distance *= iScale;
- MaxDist = distance;
- }
- return hit;
-}
-
-bool GameObjectModel::UpdatePosition()
-{
- if (!iModel)
- return false;
-
- ModelList::const_iterator it = model_list.find(owner->GetDisplayId());
- if (it == model_list.end())
- return false;
-
- G3D::AABox mdl_box(it->second.bound);
- // ignore models with no bounds
- if (mdl_box == G3D::AABox::zero())
- {
- VMAP_ERROR_LOG("misc", "GameObject model %s has zero bounds, loading skipped", it->second.name.c_str());
- return false;
- }
-
- iPos = owner->GetPosition();
-
- G3D::Matrix3 iRotation = G3D::Matrix3::fromEulerAnglesZYX(owner->GetOrientation(), 0, 0);
- iInvRot = iRotation.inverse();
- // transform bounding box:
- mdl_box = AABox(mdl_box.low() * iScale, mdl_box.high() * iScale);
- AABox rotated_bounds;
- for (int i = 0; i < 8; ++i)
- rotated_bounds.merge(iRotation * mdl_box.corner(i));
-
- iBound = rotated_bounds + iPos;
-#ifdef SPAWN_CORNERS
- // test:
- for (int i = 0; i < 8; ++i)
- {
- Vector3 pos(iBound.corner(i));
- owner->DebugVisualizeCorner(pos);
- }
-#endif
-
- return true;
-}
diff --git a/src/server/collision/Models/GameObjectModel.h b/src/server/collision/Models/GameObjectModel.h
deleted file mode 100644
index 17669189af5..00000000000
--- a/src/server/collision/Models/GameObjectModel.h
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * Copyright (C) 2008-2015 TrinityCore <http://www.trinitycore.org/>
- * 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, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef _GAMEOBJECT_MODEL_H
-#define _GAMEOBJECT_MODEL_H
-
-#include <G3D/Matrix3.h>
-#include <G3D/Vector3.h>
-#include <G3D/AABox.h>
-#include <G3D/Ray.h>
-
-#include "Define.h"
-#include <memory>
-
-namespace VMAP
-{
- class WorldModel;
-}
-
-class GameObject;
-struct GameObjectDisplayInfoEntry;
-
-class GameObjectModelOwnerBase
-{
-public:
- virtual bool IsSpawned() const { return false; }
- virtual uint32 GetDisplayId() const { return 0; }
- virtual uint32 GetPhaseMask() const { return 0; }
- virtual G3D::Vector3 GetPosition() const { return G3D::Vector3::zero(); }
- virtual float GetOrientation() const { return 0.0f; }
- virtual float GetScale() const { return 1.0f; }
- virtual void DebugVisualizeCorner(G3D::Vector3 const& /*corner*/) const { }
-};
-
-class GameObjectModel /*, public Intersectable*/
-{
- GameObjectModel() : phasemask(0), iInvScale(0), iScale(0), iModel(NULL) { }
-public:
- std::string name;
-
- const G3D::AABox& getBounds() const { return iBound; }
-
- ~GameObjectModel();
-
- const G3D::Vector3& getPosition() const { return iPos;}
-
- /** Enables\disables collision. */
- void disable() { phasemask = 0;}
- void enable(uint32 ph_mask) { phasemask = ph_mask;}
-
- bool isEnabled() const {return phasemask != 0;}
-
- bool intersectRay(const G3D::Ray& Ray, float& MaxDist, bool StopAtFirstHit, uint32 ph_mask) const;
-
- static GameObjectModel* Create(std::unique_ptr<GameObjectModelOwnerBase> modelOwner, std::string const& dataPath);
-
- bool UpdatePosition();
-
-private:
- bool initialize(std::unique_ptr<GameObjectModelOwnerBase> modelOwner, std::string const& dataPath);
-
- uint32 phasemask;
- G3D::AABox iBound;
- G3D::Matrix3 iInvRot;
- G3D::Vector3 iPos;
- float iInvScale;
- float iScale;
- VMAP::WorldModel* iModel;
- std::unique_ptr<GameObjectModelOwnerBase> owner;
-};
-
-#endif // _GAMEOBJECT_MODEL_H
diff --git a/src/server/collision/Models/ModelInstance.cpp b/src/server/collision/Models/ModelInstance.cpp
deleted file mode 100644
index 45440a99666..00000000000
--- a/src/server/collision/Models/ModelInstance.cpp
+++ /dev/null
@@ -1,222 +0,0 @@
-/*
- * Copyright (C) 2008-2015 TrinityCore <http://www.trinitycore.org/>
- * 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, see <http://www.gnu.org/licenses/>.
- */
-
-#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::pif()*iRot.y/180.f, G3D::pif()*iRot.x/180.f, G3D::pif()*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::finf())
- {
-// 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);
- if (hit)
- {
- 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) != 0;
- 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 != uint32(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) != 0;
- 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 != uint32(has_bound ? 17 : 11)) return false;
- check = fwrite(spawn.name.c_str(), sizeof(char), nameLen, wf);
- if (check != nameLen) return false;
- return true;
- }
-
-}
diff --git a/src/server/collision/Models/ModelInstance.h b/src/server/collision/Models/ModelInstance.h
deleted file mode 100644
index dfdb001db0a..00000000000
--- a/src/server/collision/Models/ModelInstance.h
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * Copyright (C) 2008-2015 TrinityCore <http://www.trinitycore.org/>
- * 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, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef _MODELINSTANCE_H_
-#define _MODELINSTANCE_H_
-
-#include <G3D/Matrix3.h>
-#include <G3D/Vector3.h>
-#include <G3D/AABox.h>
-#include <G3D/Ray.h>
-
-#include "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(): iInvScale(0.0f), iModel(nullptr) { }
- ModelInstance(const ModelSpawn &spawn, WorldModel* model);
- void setUnloaded() { iModel = nullptr; }
- 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;
- public:
- WorldModel* getWorldModel();
- };
-} // namespace VMAP
-
-#endif // _MODELINSTANCE
diff --git a/src/server/collision/Models/WorldModel.cpp b/src/server/collision/Models/WorldModel.cpp
deleted file mode 100644
index 86ab9366c71..00000000000
--- a/src/server/collision/Models/WorldModel.cpp
+++ /dev/null
@@ -1,585 +0,0 @@
-/*
- * Copyright (C) 2008-2015 TrinityCore <http://www.trinitycore.org/>
- * 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, see <http://www.gnu.org/licenses/>.
- */
-
-#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 (std::fabs(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(nullptr), iFlags(nullptr)
- {
- *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 = nullptr;
- if (other.iFlags)
- {
- iFlags = new uint8[iTilesX * iTilesY];
- memcpy(iFlags, other.iFlags, iTilesX * iTilesY);
- }
- else
- iFlags = nullptr;
- return *this;
- }
-
- bool WmoLiquid::GetLiquidHeight(const Vector3 &pos, float &liqHeight) const
- {
- float tx_f = (pos.x - iCorner.x)/LIQUID_TILE_SIZE;
- uint32 tx = uint32(tx_f);
- if (tx_f < 0.0f || tx >= iTilesX)
- return false;
- float ty_f = (pos.y - iCorner.y)/LIQUID_TILE_SIZE;
- uint32 ty = uint32(ty_f);
- if (ty_f < 0.0f || ty >= iTilesY)
- return false;
-
- // check if tile shall be used for liquid level
- // checking for 0x08 *might* be enough, but disabled tiles always are 0x?F:
- if ((iFlags[tx + ty*iTilesX] & 0x0F) == 0x0F)
- return false;
-
- // (dx, dy) coordinates inside tile, in [0, 1]^2
- float dx = tx_f - (float)tx;
- float dy = ty_f - (float)ty;
-
- /* Tesselate tile to two triangles (not sure if client does it exactly like this)
-
- ^ dy
- |
- 1 x---------x (1, 1)
- | (b) / |
- | / |
- | / |
- | / (a) |
- x---------x---> dx
- 0 1
- */
-
- const uint32 rowOffset = iTilesX + 1;
- if (dx > dy) // case (a)
- {
- float sx = iHeight[tx+1 + ty * rowOffset] - iHeight[tx + ty * rowOffset];
- float sy = iHeight[tx+1 + (ty+1) * rowOffset] - iHeight[tx+1 + ty * rowOffset];
- liqHeight = iHeight[tx + ty * rowOffset] + dx * sx + dy * sy;
- }
- else // case (b)
- {
- float sx = iHeight[tx+1 + (ty+1) * rowOffset] - iHeight[tx + (ty+1) * rowOffset];
- float sy = iHeight[tx + (ty+1) * rowOffset] - iHeight[tx + ty * rowOffset];
- liqHeight = iHeight[tx + ty * rowOffset] + dx * sx + dy * sy;
- }
- 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 = false;
- if (fwrite(&iTilesX, sizeof(uint32), 1, wf) == 1 &&
- fwrite(&iTilesY, sizeof(uint32), 1, wf) == 1 &&
- fwrite(&iCorner, sizeof(Vector3), 1, wf) == 1 &&
- fwrite(&iType, sizeof(uint32), 1, wf) == 1)
- {
- uint32 size = (iTilesX + 1) * (iTilesY + 1);
- if (fwrite(iHeight, sizeof(float), size, wf) == size)
- {
- size = iTilesX*iTilesY;
- result = fwrite(iFlags, sizeof(uint8), size, wf) == size;
- }
- }
-
- return result;
- }
-
- bool WmoLiquid::readFromFile(FILE* rf, WmoLiquid* &out)
- {
- bool result = false;
- WmoLiquid* liquid = new WmoLiquid();
-
- if (fread(&liquid->iTilesX, sizeof(uint32), 1, rf) == 1 &&
- fread(&liquid->iTilesY, sizeof(uint32), 1, rf) == 1 &&
- fread(&liquid->iCorner, sizeof(Vector3), 1, rf) == 1 &&
- fread(&liquid->iType, sizeof(uint32), 1, rf) == 1)
- {
- uint32 size = (liquid->iTilesX + 1) * (liquid->iTilesY + 1);
- liquid->iHeight = new float[size];
- if (fread(liquid->iHeight, sizeof(float), size, rf) == size)
- {
- size = liquid->iTilesX * liquid->iTilesY;
- liquid->iFlags = new uint8[size];
- result = fread(liquid->iFlags, sizeof(uint8), size, rf) == size;
- }
- }
-
- if (!result)
- delete liquid;
- else
- 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(nullptr)
- {
- 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 = 0;
- uint32 count = 0;
- triangles.clear();
- vertices.clear();
- delete iLiquid;
- iLiquid = NULL;
-
- 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.empty())
- 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.empty() || !iBound.contains(pos))
- return false;
- GModelRayCallback callback(triangles, vertices);
- Vector3 rPos = pos - 0.1f * down;
- float dist = G3D::finf();
- 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
- {
- if (iLiquid)
- return 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::finf()), zDist(G3D::finf()), 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.empty())
- 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.empty())
- 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;
-
- uint32 chunkSize, count;
- bool 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 = 0;
- uint32 count = 0;
- 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;
- }
-}
diff --git a/src/server/collision/Models/WorldModel.h b/src/server/collision/Models/WorldModel.h
deleted file mode 100644
index 6a901a59fdf..00000000000
--- a/src/server/collision/Models/WorldModel.h
+++ /dev/null
@@ -1,129 +0,0 @@
-/*
- * Copyright (C) 2008-2015 TrinityCore <http://www.trinitycore.org/>
- * 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, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef _WORLDMODEL_H
-#define _WORLDMODEL_H
-
-#include <G3D/HashTrait.h>
-#include <G3D/Vector3.h>
-#include <G3D/AABox.h>
-#include <G3D/Ray.h>
-#include "BoundingIntervalHierarchy.h"
-
-#include "Define.h"
-
-namespace VMAP
-{
- class TreeNode;
- struct AreaInfo;
- struct LocationInfo;
-
- class MeshTriangle
- {
- public:
- MeshTriangle() : idx0(0), idx1(0), idx2(0) { }
- 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 G3D::Vector3 &corner, uint32 type);
- WmoLiquid(const WmoLiquid &other);
- ~WmoLiquid();
- WmoLiquid& operator=(const WmoLiquid &other);
- bool GetLiquidHeight(const G3D::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() : iTilesX(0), iTilesY(0), iCorner(), iType(0), iHeight(NULL), iFlags(NULL) { }
- uint32 iTilesX; //!< number of tiles in x direction, each
- uint32 iTilesY;
- G3D::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
- public:
- void getPosInfo(uint32 &tilesX, uint32 &tilesY, G3D::Vector3 &corner) const;
- };
-
- /*! holding additional info for WMO group files */
- class GroupModel
- {
- public:
- GroupModel() : iBound(), iMogpFlags(0), iGroupWMOID(0), iLiquid(NULL) { }
- GroupModel(const GroupModel &other);
- GroupModel(uint32 mogpFlags, uint32 groupWMOID, const G3D::AABox &bound):
- iBound(bound), iMogpFlags(mogpFlags), iGroupWMOID(groupWMOID), iLiquid(NULL) { }
- ~GroupModel() { delete iLiquid; }
-
- //! pass mesh data to object and create BIH. Passed vectors get get swapped with old geometry!
- void setMeshData(std::vector<G3D::Vector3> &vert, std::vector<MeshTriangle> &tri);
- void setLiquidData(WmoLiquid*& liquid) { iLiquid = liquid; liquid = NULL; }
- bool IntersectRay(const G3D::Ray &ray, float &distance, bool stopAtFirstHit) const;
- bool IsInsideObject(const G3D::Vector3 &pos, const G3D::Vector3 &down, float &z_dist) const;
- bool GetLiquidLevel(const G3D::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<G3D::Vector3> vertices;
- std::vector<MeshTriangle> triangles;
- BIH meshTree;
- WmoLiquid* iLiquid;
- public:
- void getMeshData(std::vector<G3D::Vector3> &vertices, std::vector<MeshTriangle> &triangles, WmoLiquid* &liquid);
- };
- /*! 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;
- public:
- void getGroupModels(std::vector<GroupModel> &groupModels);
- };
-} // namespace VMAP
-
-#endif // _WORLDMODEL_H
diff --git a/src/server/collision/PrecompiledHeaders/collisionPCH.cpp b/src/server/collision/PrecompiledHeaders/collisionPCH.cpp
deleted file mode 100644
index 36eae8e2b0d..00000000000
--- a/src/server/collision/PrecompiledHeaders/collisionPCH.cpp
+++ /dev/null
@@ -1 +0,0 @@
-#include "collisionPCH.h"
diff --git a/src/server/collision/PrecompiledHeaders/collisionPCH.h b/src/server/collision/PrecompiledHeaders/collisionPCH.h
deleted file mode 100644
index ece2ef1b8ef..00000000000
--- a/src/server/collision/PrecompiledHeaders/collisionPCH.h
+++ /dev/null
@@ -1,9 +0,0 @@
-#include "Define.h"
-#include "VMapDefinitions.h"
-#include "MapTree.h"
-#include "WorldModel.h"
-#include "ModelInstance.h"
-#include "BoundingIntervalHierarchy.h"
-#include "RegularGrid.h"
-#include "BoundingIntervalHierarchyWrapper.h"
-#include "GameObjectModel.h"
diff --git a/src/server/collision/RegularGrid.h b/src/server/collision/RegularGrid.h
deleted file mode 100644
index 6a2a07968ad..00000000000
--- a/src/server/collision/RegularGrid.h
+++ /dev/null
@@ -1,212 +0,0 @@
-#ifndef _REGULAR_GRID_H
-#define _REGULAR_GRID_H
-
-
-#include <G3D/Ray.h>
-#include <G3D/Table.h>
-#include <G3D/BoundsTrait.h>
-#include <G3D/PositionTrait.h>
-
-#include "Errors.h"
-
-template<class Node>
-struct NodeCreator{
- static Node * makeNode(int /*x*/, int /*y*/) { return new Node();}
-};
-
-template<class T,
-class Node,
-class NodeCreatorFunc = NodeCreator<Node>,
- /*class BoundsFunc = BoundsTrait<T>,*/
-class PositionFunc = PositionTrait<T>
->
-class RegularGrid2D
-{
-public:
-
- enum{
- CELL_NUMBER = 64,
- };
-
- #define HGRID_MAP_SIZE (533.33333f * 64.f) // shouldn't be changed
- #define CELL_SIZE float(HGRID_MAP_SIZE/(float)CELL_NUMBER)
-
- typedef G3D::Table<const T*, Node*> MemberTable;
-
- MemberTable memberTable;
- Node* nodes[CELL_NUMBER][CELL_NUMBER];
-
- RegularGrid2D(){
- memset(nodes, 0, sizeof(nodes));
- }
-
- ~RegularGrid2D(){
- for (int x = 0; x < CELL_NUMBER; ++x)
- for (int y = 0; y < CELL_NUMBER; ++y)
- delete nodes[x][y];
- }
-
- void insert(const T& value)
- {
- G3D::Vector3 pos;
- PositionFunc::getPosition(value, pos);
- Node& node = getGridFor(pos.x, pos.y);
- node.insert(value);
- memberTable.set(&value, &node);
- }
-
- void remove(const T& value)
- {
- memberTable[&value]->remove(value);
- // Remove the member
- memberTable.remove(&value);
- }
-
- void balance()
- {
- for (int x = 0; x < CELL_NUMBER; ++x)
- for (int y = 0; y < CELL_NUMBER; ++y)
- if (Node* n = nodes[x][y])
- n->balance();
- }
-
- bool contains(const T& value) const { return memberTable.containsKey(&value); }
- int size() const { return memberTable.size(); }
-
- struct Cell
- {
- int x, y;
- bool operator == (const Cell& c2) const { return x == c2.x && y == c2.y;}
-
- static Cell ComputeCell(float fx, float fy)
- {
- Cell c = { int(fx * (1.f/CELL_SIZE) + (CELL_NUMBER/2)), int(fy * (1.f/CELL_SIZE) + (CELL_NUMBER/2)) };
- return c;
- }
-
- bool isValid() const { return x >= 0 && x < CELL_NUMBER && y >= 0 && y < CELL_NUMBER;}
- };
-
-
- Node& getGridFor(float fx, float fy)
- {
- Cell c = Cell::ComputeCell(fx, fy);
- return getGrid(c.x, c.y);
- }
-
- Node& getGrid(int x, int y)
- {
- ASSERT(x < CELL_NUMBER && y < CELL_NUMBER);
- if (!nodes[x][y])
- nodes[x][y] = NodeCreatorFunc::makeNode(x, y);
- return *nodes[x][y];
- }
-
- template<typename RayCallback>
- void intersectRay(const G3D::Ray& ray, RayCallback& intersectCallback, float max_dist)
- {
- intersectRay(ray, intersectCallback, max_dist, ray.origin() + ray.direction() * max_dist);
- }
-
- template<typename RayCallback>
- void intersectRay(const G3D::Ray& ray, RayCallback& intersectCallback, float& max_dist, const G3D::Vector3& end)
- {
- Cell cell = Cell::ComputeCell(ray.origin().x, ray.origin().y);
- if (!cell.isValid())
- return;
-
- Cell last_cell = Cell::ComputeCell(end.x, end.y);
-
- if (cell == last_cell)
- {
- if (Node* node = nodes[cell.x][cell.y])
- node->intersectRay(ray, intersectCallback, max_dist);
- return;
- }
-
- float voxel = (float)CELL_SIZE;
- float kx_inv = ray.invDirection().x, bx = ray.origin().x;
- float ky_inv = ray.invDirection().y, by = ray.origin().y;
-
- int stepX, stepY;
- float tMaxX, tMaxY;
- if (kx_inv >= 0)
- {
- stepX = 1;
- float x_border = (cell.x+1) * voxel;
- tMaxX = (x_border - bx) * kx_inv;
- }
- else
- {
- stepX = -1;
- float x_border = (cell.x-1) * voxel;
- tMaxX = (x_border - bx) * kx_inv;
- }
-
- if (ky_inv >= 0)
- {
- stepY = 1;
- float y_border = (cell.y+1) * voxel;
- tMaxY = (y_border - by) * ky_inv;
- }
- else
- {
- stepY = -1;
- float y_border = (cell.y-1) * voxel;
- tMaxY = (y_border - by) * ky_inv;
- }
-
- //int Cycles = std::max((int)ceilf(max_dist/tMaxX),(int)ceilf(max_dist/tMaxY));
- //int i = 0;
-
- float tDeltaX = voxel * std::fabs(kx_inv);
- float tDeltaY = voxel * std::fabs(ky_inv);
- do
- {
- if (Node* node = nodes[cell.x][cell.y])
- {
- //float enterdist = max_dist;
- node->intersectRay(ray, intersectCallback, max_dist);
- }
- if (cell == last_cell)
- break;
- if (tMaxX < tMaxY)
- {
- tMaxX += tDeltaX;
- cell.x += stepX;
- }
- else
- {
- tMaxY += tDeltaY;
- cell.y += stepY;
- }
- //++i;
- } while (cell.isValid());
- }
-
- template<typename IsectCallback>
- void intersectPoint(const G3D::Vector3& point, IsectCallback& intersectCallback)
- {
- Cell cell = Cell::ComputeCell(point.x, point.y);
- if (!cell.isValid())
- return;
- if (Node* node = nodes[cell.x][cell.y])
- node->intersectPoint(point, intersectCallback);
- }
-
- // Optimized verson of intersectRay function for rays with vertical directions
- template<typename RayCallback>
- void intersectZAllignedRay(const G3D::Ray& ray, RayCallback& intersectCallback, float& max_dist)
- {
- Cell cell = Cell::ComputeCell(ray.origin().x, ray.origin().y);
- if (!cell.isValid())
- return;
- if (Node* node = nodes[cell.x][cell.y])
- node->intersectRay(ray, intersectCallback, max_dist);
- }
-};
-
-#undef CELL_SIZE
-#undef HGRID_MAP_SIZE
-
-#endif
diff --git a/src/server/collision/VMapDefinitions.h b/src/server/collision/VMapDefinitions.h
deleted file mode 100644
index 1035d5307cc..00000000000
--- a/src/server/collision/VMapDefinitions.h
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Copyright (C) 2008-2015 TrinityCore <http://www.trinitycore.org/>
- * 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, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef _VMAPDEFINITIONS_H
-#define _VMAPDEFINITIONS_H
-#include <cstring>
-#include <cstdio>
-
-#define LIQUID_TILE_SIZE (533.333f / 128.f)
-
-namespace VMAP
-{
- const char VMAP_MAGIC[] = "VMAP_4.1";
- const char RAW_VMAP_MAGIC[] = "VMAP041"; // used in extracted vmap files with raw data
- const char GAMEOBJECT_MODELS[] = "GameObjectModels.dtree";
-
- // defined in TileAssembler.cpp currently...
- bool readChunk(FILE* rf, char *dest, const char *compare, uint32 len);
-}
-
-// Set of helper macros for extractors (VMAP and MMAP)
-#ifndef NO_CORE_FUNCS
-#define VMAP_ERROR_LOG(FILTER, ...) TC_LOG_ERROR(FILTER, __VA_ARGS__)
-#define VMAP_DEBUG_LOG(FILTER, ...) TC_LOG_DEBUG(FILTER, __VA_ARGS__)
-#define VMAP_INFO_LOG(FILTER, ...) TC_LOG_INFO(FILTER, __VA_ARGS__)
-#else
-#define VMAP_ERROR_LOG(FILTER, ...) (void)sizeof(FILTER)
-#define VMAP_DEBUG_LOG(FILTER, ...) (void)sizeof(FILTER)
-#define VMAP_INFO_LOG(FILTER, ...) (void)sizeof(FILTER)
-#endif
-
-#endif
diff --git a/src/server/collision/VMapTools.h b/src/server/collision/VMapTools.h
deleted file mode 100644
index fa7bc394ebc..00000000000
--- a/src/server/collision/VMapTools.h
+++ /dev/null
@@ -1,150 +0,0 @@
-/*
- * Copyright (C) 2008-2015 TrinityCore <http://www.trinitycore.org/>
- * 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, see <http://www.gnu.org/licenses/>.
- */
-
-#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
diff --git a/src/server/database/CMakeLists.txt b/src/server/database/CMakeLists.txt
new file mode 100644
index 00000000000..3fa7ed10aaf
--- /dev/null
+++ b/src/server/database/CMakeLists.txt
@@ -0,0 +1,74 @@
+# Copyright (C) 2008-2015 TrinityCore <http://www.trinitycore.org/>
+#
+# This file is free software; as a special exception the author gives
+# unlimited permission to copy and/or distribute it, with or without
+# modifications, as long as this notice is preserved.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY, to the extent permitted by law; without even the
+# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+if( USE_COREPCH )
+ include_directories(${CMAKE_CURRENT_BINARY_DIR})
+endif()
+
+file(GLOB_RECURSE sources_Database Database/*.cpp Database/*.h)
+file(GLOB_RECURSE sources_Logging Logging/*.cpp Logging/*.h)
+file(GLOB_RECURSE sources_Updater Updater/*.cpp Updater/*.h)
+
+file(GLOB sources_localdir *.cpp *.h)
+
+#
+# Build shared sourcelist
+#
+
+if (USE_COREPCH)
+ set(database_STAT_PCH_HDR PrecompiledHeaders/databasePCH.h)
+ set(database_STAT_PCH_SRC PrecompiledHeaders/databasePCH.cpp)
+endif()
+
+set(database_STAT_SRCS
+ ${database_STAT_SRCS}
+ ${sources_Database}
+ ${sources_Logging}
+ ${sources_Updater}
+)
+
+include_directories(
+ ${CMAKE_BINARY_DIR}
+ ${CMAKE_SOURCE_DIR}/dep/recastnavigation/Detour
+ ${CMAKE_SOURCE_DIR}/dep/SFMT
+ ${CMAKE_SOURCE_DIR}/dep/cppformat
+ ${CMAKE_SOURCE_DIR}/dep/utf8cpp
+ ${CMAKE_SOURCE_DIR}/dep/process
+ ${CMAKE_SOURCE_DIR}/src/server
+ ${CMAKE_CURRENT_SOURCE_DIR}
+ ${CMAKE_CURRENT_SOURCE_DIR}/Database
+ ${CMAKE_CURRENT_SOURCE_DIR}/Logging
+ ${CMAKE_CURRENT_SOURCE_DIR}/Updater
+ ${CMAKE_SOURCE_DIR}/src/common/
+ ${CMAKE_SOURCE_DIR}/src/common/Collision
+ ${CMAKE_SOURCE_DIR}/src/common/Collision/Management
+ ${CMAKE_SOURCE_DIR}/src/common/Collision/Models
+ ${CMAKE_SOURCE_DIR}/src/common/Debugging
+ ${CMAKE_SOURCE_DIR}/src/common/Threading
+ ${CMAKE_SOURCE_DIR}/src/common/Utilities
+ ${CMAKE_SOURCE_DIR}/src/common/Configuration
+ ${CMAKE_SOURCE_DIR}/src/common/Logging
+ ${CMAKE_SOURCE_DIR}/src/server/shared
+ ${MYSQL_INCLUDE_DIR}
+ ${OPENSSL_INCLUDE_DIR} # seems needed for Windows build
+ ${VALGRIND_INCLUDE_DIR}
+)
+
+GroupSources(${CMAKE_CURRENT_SOURCE_DIR})
+
+add_library(database STATIC
+ ${database_STAT_SRCS}
+ ${database_STAT_PCH_SRC}
+)
+
+# Generate precompiled header
+if (USE_COREPCH)
+ add_cxx_pch(database ${database_STAT_PCH_HDR} ${database_STAT_PCH_SRC})
+endif ()
diff --git a/src/server/shared/Database/AdhocStatement.cpp b/src/server/database/Database/AdhocStatement.cpp
index 547ff967efe..547ff967efe 100644
--- a/src/server/shared/Database/AdhocStatement.cpp
+++ b/src/server/database/Database/AdhocStatement.cpp
diff --git a/src/server/shared/Database/AdhocStatement.h b/src/server/database/Database/AdhocStatement.h
index c449e0f6e59..c449e0f6e59 100644
--- a/src/server/shared/Database/AdhocStatement.h
+++ b/src/server/database/Database/AdhocStatement.h
diff --git a/src/server/shared/Database/DatabaseEnv.h b/src/server/database/Database/DatabaseEnv.h
index c3e11c5b98e..c3e11c5b98e 100644
--- a/src/server/shared/Database/DatabaseEnv.h
+++ b/src/server/database/Database/DatabaseEnv.h
diff --git a/src/server/shared/Database/DatabaseLoader.cpp b/src/server/database/Database/DatabaseLoader.cpp
index a3e2083fff4..a3e2083fff4 100644
--- a/src/server/shared/Database/DatabaseLoader.cpp
+++ b/src/server/database/Database/DatabaseLoader.cpp
diff --git a/src/server/shared/Database/DatabaseLoader.h b/src/server/database/Database/DatabaseLoader.h
index d35597ba807..d35597ba807 100644
--- a/src/server/shared/Database/DatabaseLoader.h
+++ b/src/server/database/Database/DatabaseLoader.h
diff --git a/src/server/shared/Database/DatabaseWorker.cpp b/src/server/database/Database/DatabaseWorker.cpp
index 56757ce12a0..56757ce12a0 100644
--- a/src/server/shared/Database/DatabaseWorker.cpp
+++ b/src/server/database/Database/DatabaseWorker.cpp
diff --git a/src/server/shared/Database/DatabaseWorker.h b/src/server/database/Database/DatabaseWorker.h
index 0ca476b1e66..0ca476b1e66 100644
--- a/src/server/shared/Database/DatabaseWorker.h
+++ b/src/server/database/Database/DatabaseWorker.h
diff --git a/src/server/shared/Database/DatabaseWorkerPool.h b/src/server/database/Database/DatabaseWorkerPool.h
index f5002c6943b..f5002c6943b 100644
--- a/src/server/shared/Database/DatabaseWorkerPool.h
+++ b/src/server/database/Database/DatabaseWorkerPool.h
diff --git a/src/server/shared/Database/Field.cpp b/src/server/database/Database/Field.cpp
index 89195b699b7..89195b699b7 100644
--- a/src/server/shared/Database/Field.cpp
+++ b/src/server/database/Database/Field.cpp
diff --git a/src/server/shared/Database/Field.h b/src/server/database/Database/Field.h
index 1bbd264482f..1bbd264482f 100644
--- a/src/server/shared/Database/Field.h
+++ b/src/server/database/Database/Field.h
diff --git a/src/server/shared/Database/Implementation/CharacterDatabase.cpp b/src/server/database/Database/Implementation/CharacterDatabase.cpp
index 1efdb16804f..1efdb16804f 100644
--- a/src/server/shared/Database/Implementation/CharacterDatabase.cpp
+++ b/src/server/database/Database/Implementation/CharacterDatabase.cpp
diff --git a/src/server/shared/Database/Implementation/CharacterDatabase.h b/src/server/database/Database/Implementation/CharacterDatabase.h
index f88a912e022..f88a912e022 100644
--- a/src/server/shared/Database/Implementation/CharacterDatabase.h
+++ b/src/server/database/Database/Implementation/CharacterDatabase.h
diff --git a/src/server/shared/Database/Implementation/LoginDatabase.cpp b/src/server/database/Database/Implementation/LoginDatabase.cpp
index 8f0b5067957..8f0b5067957 100644
--- a/src/server/shared/Database/Implementation/LoginDatabase.cpp
+++ b/src/server/database/Database/Implementation/LoginDatabase.cpp
diff --git a/src/server/shared/Database/Implementation/LoginDatabase.h b/src/server/database/Database/Implementation/LoginDatabase.h
index 7f6cffa520f..7f6cffa520f 100644
--- a/src/server/shared/Database/Implementation/LoginDatabase.h
+++ b/src/server/database/Database/Implementation/LoginDatabase.h
diff --git a/src/server/shared/Database/Implementation/WorldDatabase.cpp b/src/server/database/Database/Implementation/WorldDatabase.cpp
index d9aad94293e..d9aad94293e 100644
--- a/src/server/shared/Database/Implementation/WorldDatabase.cpp
+++ b/src/server/database/Database/Implementation/WorldDatabase.cpp
diff --git a/src/server/shared/Database/Implementation/WorldDatabase.h b/src/server/database/Database/Implementation/WorldDatabase.h
index 36fd6fbb186..36fd6fbb186 100644
--- a/src/server/shared/Database/Implementation/WorldDatabase.h
+++ b/src/server/database/Database/Implementation/WorldDatabase.h
diff --git a/src/server/shared/Database/MySQLConnection.cpp b/src/server/database/Database/MySQLConnection.cpp
index 10f4a7baa18..10f4a7baa18 100644
--- a/src/server/shared/Database/MySQLConnection.cpp
+++ b/src/server/database/Database/MySQLConnection.cpp
diff --git a/src/server/shared/Database/MySQLConnection.h b/src/server/database/Database/MySQLConnection.h
index 78d8d2fb5dd..78d8d2fb5dd 100644
--- a/src/server/shared/Database/MySQLConnection.h
+++ b/src/server/database/Database/MySQLConnection.h
diff --git a/src/server/shared/Database/MySQLThreading.h b/src/server/database/Database/MySQLThreading.h
index 441f30cb6ec..441f30cb6ec 100644
--- a/src/server/shared/Database/MySQLThreading.h
+++ b/src/server/database/Database/MySQLThreading.h
diff --git a/src/server/shared/Database/PreparedStatement.cpp b/src/server/database/Database/PreparedStatement.cpp
index 1938005c712..1938005c712 100644
--- a/src/server/shared/Database/PreparedStatement.cpp
+++ b/src/server/database/Database/PreparedStatement.cpp
diff --git a/src/server/shared/Database/PreparedStatement.h b/src/server/database/Database/PreparedStatement.h
index 2b8ce8aac2d..2b8ce8aac2d 100644
--- a/src/server/shared/Database/PreparedStatement.h
+++ b/src/server/database/Database/PreparedStatement.h
diff --git a/src/server/shared/Database/QueryHolder.cpp b/src/server/database/Database/QueryHolder.cpp
index 2fdb3825526..2fdb3825526 100644
--- a/src/server/shared/Database/QueryHolder.cpp
+++ b/src/server/database/Database/QueryHolder.cpp
diff --git a/src/server/shared/Database/QueryHolder.h b/src/server/database/Database/QueryHolder.h
index b64da948a16..b64da948a16 100644
--- a/src/server/shared/Database/QueryHolder.h
+++ b/src/server/database/Database/QueryHolder.h
diff --git a/src/server/shared/Database/QueryResult.cpp b/src/server/database/Database/QueryResult.cpp
index 02352f221a0..02352f221a0 100644
--- a/src/server/shared/Database/QueryResult.cpp
+++ b/src/server/database/Database/QueryResult.cpp
diff --git a/src/server/shared/Database/QueryResult.h b/src/server/database/Database/QueryResult.h
index a61fb6331c1..a61fb6331c1 100644
--- a/src/server/shared/Database/QueryResult.h
+++ b/src/server/database/Database/QueryResult.h
diff --git a/src/server/shared/Database/SQLOperation.h b/src/server/database/Database/SQLOperation.h
index c5667288ec0..c5667288ec0 100644
--- a/src/server/shared/Database/SQLOperation.h
+++ b/src/server/database/Database/SQLOperation.h
diff --git a/src/server/shared/Database/Transaction.cpp b/src/server/database/Database/Transaction.cpp
index f657411f716..f657411f716 100644
--- a/src/server/shared/Database/Transaction.cpp
+++ b/src/server/database/Database/Transaction.cpp
diff --git a/src/server/shared/Database/Transaction.h b/src/server/database/Database/Transaction.h
index 4fbbe1ed45b..4fbbe1ed45b 100644
--- a/src/server/shared/Database/Transaction.h
+++ b/src/server/database/Database/Transaction.h
diff --git a/src/server/shared/Logging/AppenderDB.cpp b/src/server/database/Logging/AppenderDB.cpp
index 9e6ab1a057c..9e6ab1a057c 100644
--- a/src/server/shared/Logging/AppenderDB.cpp
+++ b/src/server/database/Logging/AppenderDB.cpp
diff --git a/src/server/shared/Logging/AppenderDB.h b/src/server/database/Logging/AppenderDB.h
index 50607fd8136..50607fd8136 100644
--- a/src/server/shared/Logging/AppenderDB.h
+++ b/src/server/database/Logging/AppenderDB.h
diff --git a/src/server/database/PrecompiledHeaders/databasePCH.cpp b/src/server/database/PrecompiledHeaders/databasePCH.cpp
new file mode 100644
index 00000000000..f84a52be82a
--- /dev/null
+++ b/src/server/database/PrecompiledHeaders/databasePCH.cpp
@@ -0,0 +1 @@
+#include "PrecompiledHeaders/databasePCH.h"
diff --git a/src/server/database/PrecompiledHeaders/databasePCH.h b/src/server/database/PrecompiledHeaders/databasePCH.h
new file mode 100644
index 00000000000..d524d52ade0
--- /dev/null
+++ b/src/server/database/PrecompiledHeaders/databasePCH.h
@@ -0,0 +1,23 @@
+#include "Config.h"
+#include "Database/AdhocStatement.h"
+#include "Database/DatabaseEnv.h"
+#include "Database/DatabaseLoader.h"
+#include "Database/DatabaseWorker.h"
+#include "Database/DatabaseWorkerPool.h"
+#include "Database/Field.h"
+#include "Database/MySQLConnection.h"
+#include "Database/MySQLThreading.h"
+#include "Database/PreparedStatement.h"
+#include "Database/QueryHolder.h"
+#include "Database/QueryResult.h"
+#include "Database/SQLOperation.h"
+#include "Database/Transaction.h"
+#include "Logging/Appender.h"
+#include "Logging/AppenderConsole.h"
+#include "Logging/AppenderDB.h"
+#include "Logging/AppenderFile.h"
+#include "Logging/Log.h"
+#include "Logging/LogOperation.h"
+#include "Logging/Logger.h"
+#include "Updater/DBUpdater.h"
+#include "Updater/UpdateFetcher.h"
diff --git a/src/server/shared/Updater/DBUpdater.cpp b/src/server/database/Updater/DBUpdater.cpp
index c69d19b11d6..c69d19b11d6 100644
--- a/src/server/shared/Updater/DBUpdater.cpp
+++ b/src/server/database/Updater/DBUpdater.cpp
diff --git a/src/server/shared/Updater/DBUpdater.h b/src/server/database/Updater/DBUpdater.h
index a2b12bed235..a2b12bed235 100644
--- a/src/server/shared/Updater/DBUpdater.h
+++ b/src/server/database/Updater/DBUpdater.h
diff --git a/src/server/shared/Updater/UpdateFetcher.cpp b/src/server/database/Updater/UpdateFetcher.cpp
index ec023928b99..ec023928b99 100644
--- a/src/server/shared/Updater/UpdateFetcher.cpp
+++ b/src/server/database/Updater/UpdateFetcher.cpp
diff --git a/src/server/shared/Updater/UpdateFetcher.h b/src/server/database/Updater/UpdateFetcher.h
index 4ff8c93bc76..4ff8c93bc76 100644
--- a/src/server/shared/Updater/UpdateFetcher.h
+++ b/src/server/database/Updater/UpdateFetcher.h
diff --git a/src/server/game/CMakeLists.txt b/src/server/game/CMakeLists.txt
index 66425ed2dc7..ccc69b3ef68 100644
--- a/src/server/game/CMakeLists.txt
+++ b/src/server/game/CMakeLists.txt
@@ -112,25 +112,28 @@ include_directories(
${CMAKE_SOURCE_DIR}/dep/SFMT
${CMAKE_SOURCE_DIR}/dep/cppformat
${CMAKE_SOURCE_DIR}/dep/zlib
- ${CMAKE_SOURCE_DIR}/src/server/collision
- ${CMAKE_SOURCE_DIR}/src/server/collision/Management
- ${CMAKE_SOURCE_DIR}/src/server/collision/Models
- ${CMAKE_SOURCE_DIR}/src/server/collision/Maps
+ ${CMAKE_SOURCE_DIR}/src/common
+ ${CMAKE_SOURCE_DIR}/src/common/Collision
+ ${CMAKE_SOURCE_DIR}/src/common/Collision/Management
+ ${CMAKE_SOURCE_DIR}/src/common/Collision/Models
+ ${CMAKE_SOURCE_DIR}/src/common/Collision/Maps
+ ${CMAKE_SOURCE_DIR}/src/common/Debugging
+ ${CMAKE_SOURCE_DIR}/src/common/Utilities
+ ${CMAKE_SOURCE_DIR}/src/common/Threading
+ ${CMAKE_SOURCE_DIR}/src/common/Configuration
+ ${CMAKE_SOURCE_DIR}/src/common/Logging
+ ${CMAKE_SOURCE_DIR}/src/server/database
+ ${CMAKE_SOURCE_DIR}/src/server/database/Database
+ ${CMAKE_SOURCE_DIR}/src/server/database/Logging
+ ${CMAKE_SOURCE_DIR}/src/server/database/Updater
${CMAKE_SOURCE_DIR}/src/server/shared
- ${CMAKE_SOURCE_DIR}/src/server/shared/Configuration
${CMAKE_SOURCE_DIR}/src/server/shared/Cryptography
${CMAKE_SOURCE_DIR}/src/server/shared/Cryptography/Authentication
- ${CMAKE_SOURCE_DIR}/src/server/shared/Database
${CMAKE_SOURCE_DIR}/src/server/shared/DataStores
- ${CMAKE_SOURCE_DIR}/src/server/shared/Debugging
${CMAKE_SOURCE_DIR}/src/server/shared/Dynamic/LinkedReference
${CMAKE_SOURCE_DIR}/src/server/shared/Dynamic
- ${CMAKE_SOURCE_DIR}/src/server/shared/Logging
${CMAKE_SOURCE_DIR}/src/server/shared/Networking
${CMAKE_SOURCE_DIR}/src/server/shared/Packets
- ${CMAKE_SOURCE_DIR}/src/server/shared/Threading
- ${CMAKE_SOURCE_DIR}/src/server/shared/Updater
- ${CMAKE_SOURCE_DIR}/src/server/shared/Utilities
${CMAKE_CURRENT_SOURCE_DIR}
${CMAKE_CURRENT_SOURCE_DIR}/Accounts
${CMAKE_CURRENT_SOURCE_DIR}/Achievements
diff --git a/src/server/scripts/CMakeLists.txt b/src/server/scripts/CMakeLists.txt
index 57f145eb15a..db15ce8c36d 100644
--- a/src/server/scripts/CMakeLists.txt
+++ b/src/server/scripts/CMakeLists.txt
@@ -52,24 +52,26 @@ include_directories(
${CMAKE_SOURCE_DIR}/dep/SFMT
${CMAKE_SOURCE_DIR}/dep/cppformat
${CMAKE_SOURCE_DIR}/dep/zlib
+ ${CMAKE_SOURCE_DIR}/src/server/database
+ ${CMAKE_SOURCE_DIR}/src/server/database/Database
+ ${CMAKE_SOURCE_DIR}/src/server/database/Logging
+ ${CMAKE_SOURCE_DIR}/src/server/database/Updater
${CMAKE_SOURCE_DIR}/src/server/shared
- ${CMAKE_SOURCE_DIR}/src/server/shared/Configuration
${CMAKE_SOURCE_DIR}/src/server/shared/Cryptography
- ${CMAKE_SOURCE_DIR}/src/server/shared/Database
${CMAKE_SOURCE_DIR}/src/server/shared/DataStores
- ${CMAKE_SOURCE_DIR}/src/server/shared/Debugging
${CMAKE_SOURCE_DIR}/src/server/shared/Dynamic/LinkedReference
${CMAKE_SOURCE_DIR}/src/server/shared/Dynamic
- ${CMAKE_SOURCE_DIR}/src/server/shared/Logging
${CMAKE_SOURCE_DIR}/src/server/shared/Packets
- ${CMAKE_SOURCE_DIR}/src/server/shared/Threading
- ${CMAKE_SOURCE_DIR}/src/server/shared/Updater
- ${CMAKE_SOURCE_DIR}/src/server/shared/Utilities
- ${CMAKE_SOURCE_DIR}/src/server/collision
- ${CMAKE_SOURCE_DIR}/src/server/collision/Management
- ${CMAKE_SOURCE_DIR}/src/server/collision/Models
+ ${CMAKE_SOURCE_DIR}/src/common/
+ ${CMAKE_SOURCE_DIR}/src/common/Collision
+ ${CMAKE_SOURCE_DIR}/src/common/Collision/Management
+ ${CMAKE_SOURCE_DIR}/src/common/Collision/Models
+ ${CMAKE_SOURCE_DIR}/src/common/Debugging
+ ${CMAKE_SOURCE_DIR}/src/common/Utilities
+ ${CMAKE_SOURCE_DIR}/src/common/Threading
+ ${CMAKE_SOURCE_DIR}/src/common/Configuration
+ ${CMAKE_SOURCE_DIR}/src/common/Logging
${CMAKE_SOURCE_DIR}/src/server/shared
- ${CMAKE_SOURCE_DIR}/src/server/shared/Database
${CMAKE_SOURCE_DIR}/src/server/game/Accounts
${CMAKE_SOURCE_DIR}/src/server/game/Achievements
${CMAKE_SOURCE_DIR}/src/server/game/Addons
diff --git a/src/server/shared/CMakeLists.txt b/src/server/shared/CMakeLists.txt
index d68ddf85ff3..1653d605faa 100644
--- a/src/server/shared/CMakeLists.txt
+++ b/src/server/shared/CMakeLists.txt
@@ -12,25 +12,16 @@ if( USE_COREPCH )
include_directories(${CMAKE_CURRENT_BINARY_DIR})
endif()
-file(GLOB_RECURSE sources_Configuration Configuration/*.cpp Configuration/*.h)
file(GLOB_RECURSE sources_Cryptography Cryptography/*.cpp Cryptography/*.h)
-file(GLOB_RECURSE sources_Database Database/*.cpp Database/*.h)
file(GLOB_RECURSE sources_DataStores DataStores/*.cpp DataStores/*.h)
file(GLOB_RECURSE sources_Dynamic Dynamic/*.cpp Dynamic/*.h)
-file(GLOB_RECURSE sources_Logging Logging/*.cpp Logging/*.h)
file(GLOB_RECURSE sources_Networking Networking/*.cpp Networking/*.h)
file(GLOB_RECURSE sources_Packets Packets/*.cpp Packets/*.h)
-file(GLOB_RECURSE sources_Threading Threading/*.cpp Threading/*.h)
-file(GLOB_RECURSE sources_Updater Updater/*.cpp Updater/*.h)
-file(GLOB_RECURSE sources_Utilities Utilities/*.cpp Utilities/*.h)
-
+if( WIN32 )
+ file(GLOB_RECURSE sources_Service Service/*.cpp Service/*.h)
+endif( WIN32 )
file(GLOB sources_localdir *.cpp *.h)
-# Manually set sources for Debugging directory as we don't want to include WheatyExceptionReport in shared project
-# It needs to be included both in authserver and worldserver for the static global variable to be properly initialized
-# and to handle crash logs on windows
-set(sources_Debugging Debugging/Errors.cpp Debugging/Errors.h)
-
#
# Build shared sourcelist
#
@@ -42,18 +33,13 @@ endif()
set(shared_STAT_SRCS
${shared_STAT_SRCS}
- ${sources_Configuration}
${sources_Cryptography}
- ${sources_Database}
${sources_DataStores}
- ${sources_Debugging}
${sources_Dynamic}
- ${sources_Logging}
${sources_Networking}
${sources_Packets}
- ${sources_Threading}
- ${sources_Updater}
${sources_Utilities}
+ ${sources_Service}
${sources_localdir}
)
@@ -65,20 +51,25 @@ include_directories(
${CMAKE_SOURCE_DIR}/dep/utf8cpp
${CMAKE_SOURCE_DIR}/dep/process
${CMAKE_SOURCE_DIR}/src/server
+ ${CMAKE_SOURCE_DIR}/src/server/database
+ ${CMAKE_SOURCE_DIR}/src/server/database/Database
+ ${CMAKE_SOURCE_DIR}/src/server/database/Logging
+ ${CMAKE_SOURCE_DIR}/src/server/database/Updater
${CMAKE_CURRENT_SOURCE_DIR}
- ${CMAKE_CURRENT_SOURCE_DIR}/Configuration
${CMAKE_CURRENT_SOURCE_DIR}/Cryptography
- ${CMAKE_CURRENT_SOURCE_DIR}/Database
${CMAKE_CURRENT_SOURCE_DIR}/DataStores
- ${CMAKE_CURRENT_SOURCE_DIR}/Debugging
${CMAKE_CURRENT_SOURCE_DIR}/Dynamic
- ${CMAKE_CURRENT_SOURCE_DIR}/Logging
${CMAKE_CURRENT_SOURCE_DIR}/Networking
${CMAKE_CURRENT_SOURCE_DIR}/Packets
- ${CMAKE_CURRENT_SOURCE_DIR}/Threading
- ${CMAKE_CURRENT_SOURCE_DIR}/Utilities
- ${CMAKE_CURRENT_SOURCE_DIR}/Updater
- ${CMAKE_SOURCE_DIR}/src/server/game/Entities/Object
+ ${CMAKE_CURRENT_SOURCE_DIR}/Service
+ ${CMAKE_SOURCE_DIR}/src/common/
+ ${CMAKE_SOURCE_DIR}/src/common/Collision
+ ${CMAKE_SOURCE_DIR}/src/common/Collision/Management
+ ${CMAKE_SOURCE_DIR}/src/common/Collision/Models
+ ${CMAKE_SOURCE_DIR}/src/common/Debugging
+ ${CMAKE_SOURCE_DIR}/src/common/Utilities
+ ${CMAKE_SOURCE_DIR}/src/common/Configuration
+ ${CMAKE_SOURCE_DIR}/src/common/Logging
${MYSQL_INCLUDE_DIR}
${OPENSSL_INCLUDE_DIR}
${VALGRIND_INCLUDE_DIR}
diff --git a/src/server/shared/Common.cpp b/src/server/shared/Common.cpp
deleted file mode 100644
index 56e3c4faaf5..00000000000
--- a/src/server/shared/Common.cpp
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Copyright (C) 2008-2015 TrinityCore <http://www.trinitycore.org/>
- * 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, see <http://www.gnu.org/licenses/>.
- */
-
-#include "Common.h"
-
-char const* localeNames[TOTAL_LOCALES] = {
- "enUS",
- "koKR",
- "frFR",
- "deDE",
- "zhCN",
- "zhTW",
- "esES",
- "esMX",
- "ruRU"
-};
-
-LocaleConstant GetLocaleByName(const std::string& name)
-{
- for (uint32 i = 0; i < TOTAL_LOCALES; ++i)
- if (name==localeNames[i])
- return LocaleConstant(i);
-
- return LOCALE_enUS; // including enGB case
-}
-
diff --git a/src/server/shared/Common.h b/src/server/shared/Common.h
deleted file mode 100644
index 09d64acc795..00000000000
--- a/src/server/shared/Common.h
+++ /dev/null
@@ -1,158 +0,0 @@
-/*
- * Copyright (C) 2008-2015 TrinityCore <http://www.trinitycore.org/>
- * 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, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef TRINITYCORE_COMMON_H
-#define TRINITYCORE_COMMON_H
-
-#include "Define.h"
-
-#include <unordered_map>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <time.h>
-#include <cmath>
-#include <errno.h>
-#include <signal.h>
-#include <assert.h>
-
-#include <set>
-#include <list>
-#include <string>
-#include <map>
-#include <queue>
-#include <sstream>
-#include <algorithm>
-#include <memory>
-
-#include "Debugging/Errors.h"
-
-#include "Threading/LockedQueue.h"
-
-#if PLATFORM == PLATFORM_WINDOWS
-# include <ws2tcpip.h>
-
-# if defined(__INTEL_COMPILER)
-# if !defined(BOOST_ASIO_HAS_MOVE)
-# define BOOST_ASIO_HAS_MOVE
-# endif // !defined(BOOST_ASIO_HAS_MOVE)
-# endif // if defined(__INTEL_COMPILER)
-
-#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 snprintf _snprintf
-#define atoll _atoi64
-#define vsnprintf _vsnprintf
-#define llabs _abs64
-
-#else
-
-#define stricmp strcasecmp
-#define strnicmp strncasecmp
-
-#endif
-
-inline float finiteAlways(float f) { return std::isfinite(f) ? f : 0.0f; }
-
-inline unsigned long atoul(char const* str) { return strtoul(str, nullptr, 10); }
-inline unsigned long long atoull(char const* str) { return strtoull(str, nullptr, 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_MILLISECONDS = 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 TOTAL_LOCALES = 9;
-#define DEFAULT_LOCALE LOCALE_enUS
-
-#define MAX_LOCALES 8
-#define MAX_ACCOUNT_TUTORIAL_VALUES 8
-
-extern char const* localeNames[TOTAL_LOCALES];
-
-LocaleConstant GetLocaleByName(const std::string& name);
-
-typedef std::vector<std::string> StringVector;
-
-// 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
-
-#define MAX_QUERY_LEN 32*1024
-
-namespace Trinity
-{
- //! std::make_unique implementation (TODO: remove this once C++14 is supported)
- template<typename T, typename ...Args>
- std::unique_ptr<T> make_unique(Args&& ...args)
- {
- return std::unique_ptr<T>(new T(std::forward<Args>(args)...));
- }
-}
-
-#endif
diff --git a/src/server/shared/CompilerDefs.h b/src/server/shared/CompilerDefs.h
deleted file mode 100644
index c7867be517b..00000000000
--- a/src/server/shared/CompilerDefs.h
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * Copyright (C) 2008-2015 TrinityCore <http://www.trinitycore.org/>
- * 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, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef TRINITY_COMPILERDEFS_H
-#define TRINITY_COMPILERDEFS_H
-
-#define PLATFORM_WINDOWS 0
-#define PLATFORM_UNIX 1
-#define PLATFORM_APPLE 2
-#define PLATFORM_INTEL 3
-
-// must be first (win 64 also define _WIN32)
-#if defined( _WIN64 )
-# define PLATFORM PLATFORM_WINDOWS
-#elif defined( __WIN32__ ) || defined( WIN32 ) || defined( _WIN32 )
-# define PLATFORM PLATFORM_WINDOWS
-#elif defined( __APPLE_CC__ )
-# define PLATFORM PLATFORM_APPLE
-#elif defined( __INTEL_COMPILER )
-# define PLATFORM PLATFORM_INTEL
-#else
-# define PLATFORM PLATFORM_UNIX
-#endif
-
-#define COMPILER_MICROSOFT 0
-#define COMPILER_GNU 1
-#define COMPILER_BORLAND 2
-#define COMPILER_INTEL 3
-
-#ifdef _MSC_VER
-# define COMPILER COMPILER_MICROSOFT
-#elif defined( __BORLANDC__ )
-# define COMPILER COMPILER_BORLAND
-#elif defined( __INTEL_COMPILER )
-# define COMPILER COMPILER_INTEL
-#elif defined( __GNUC__ )
-# define COMPILER COMPILER_GNU
-# define GCC_VERSION (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__)
-#else
-# error "FATAL ERROR: Unknown compiler."
-#endif
-
-#endif
diff --git a/src/server/shared/Configuration/Config.cpp b/src/server/shared/Configuration/Config.cpp
deleted file mode 100644
index ea426a5d33e..00000000000
--- a/src/server/shared/Configuration/Config.cpp
+++ /dev/null
@@ -1,114 +0,0 @@
-/*
- * Copyright (C) 2008-2015 TrinityCore <http://www.trinitycore.org/>
- * 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, see <http://www.gnu.org/licenses/>.
- */
-
-#include <algorithm>
-#include <mutex>
-#include <boost/property_tree/ptree.hpp>
-#include <boost/property_tree/ini_parser.hpp>
-#include "Config.h"
-
-using namespace boost::property_tree;
-
-bool ConfigMgr::LoadInitial(std::string const& file, std::string& error)
-{
- std::lock_guard<std::mutex> lock(_configLock);
-
- _filename = file;
-
- try
- {
- ptree fullTree;
- ini_parser::read_ini(file, fullTree);
-
- if (fullTree.empty())
- {
- error = "empty file (" + file + ")";
- return false;
- }
-
- // Since we're using only one section per config file, we skip the section and have direct property access
- _config = fullTree.begin()->second;
- }
- catch (ini_parser::ini_parser_error const& e)
- {
- if (e.line() == 0)
- error = e.message() + " (" + e.filename() + ")";
- else
- error = e.message() + " (" + e.filename() + ":" + std::to_string(e.line()) + ")";
- return false;
- }
-
- return true;
-}
-
-bool ConfigMgr::Reload(std::string& error)
-{
- return LoadInitial(_filename, error);
-}
-
-std::string ConfigMgr::GetStringDefault(std::string const& name, const std::string& def)
-{
- std::string value = _config.get<std::string>(ptree::path_type(name, '/'), def);
-
- value.erase(std::remove(value.begin(), value.end(), '"'), value.end());
-
- return value;
-}
-
-bool ConfigMgr::GetBoolDefault(std::string const& name, bool def)
-{
- try
- {
- std::string val = _config.get<std::string>(ptree::path_type(name, '/'));
- val.erase(std::remove(val.begin(), val.end(), '"'), val.end());
- return (val == "true" || val == "TRUE" || val == "yes" || val == "YES" || val == "1");
- }
- catch (std::exception const& /*ex*/)
- {
- return def;
- }
-}
-
-int ConfigMgr::GetIntDefault(std::string const& name, int def)
-{
- return _config.get<int>(ptree::path_type(name, '/'), def);
-}
-
-float ConfigMgr::GetFloatDefault(std::string const& name, float def)
-{
- return _config.get<float>(ptree::path_type(name, '/'), def);
-}
-
-std::string const& ConfigMgr::GetFilename()
-{
- std::lock_guard<std::mutex> lock(_configLock);
- return _filename;
-}
-
-std::list<std::string> ConfigMgr::GetKeysByString(std::string const& name)
-{
- std::lock_guard<std::mutex> lock(_configLock);
-
- std::list<std::string> keys;
-
- for (const ptree::value_type& child : _config)
- if (child.first.compare(0, name.length(), name) == 0)
- keys.push_back(child.first);
-
- return keys;
-}
diff --git a/src/server/shared/Configuration/Config.h b/src/server/shared/Configuration/Config.h
deleted file mode 100644
index 5fb7cef9241..00000000000
--- a/src/server/shared/Configuration/Config.h
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * Copyright (C) 2008-2015 TrinityCore <http://www.trinitycore.org/>
- * 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, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef CONFIG_H
-#define CONFIG_H
-
-#include <string>
-#include <list>
-#include <mutex>
-#include <boost/property_tree/ptree.hpp>
-
-class ConfigMgr
-{
- ConfigMgr() { }
- ~ConfigMgr() { }
-
-public:
- /// Method used only for loading main configuration files (authserver.conf and worldserver.conf)
- bool LoadInitial(std::string const& file, std::string& error);
-
- static ConfigMgr* instance()
- {
- static ConfigMgr instance;
- return &instance;
- }
-
- bool Reload(std::string& error);
-
- std::string GetStringDefault(std::string const& name, const std::string& def);
- bool GetBoolDefault(std::string const& name, bool def);
- int GetIntDefault(std::string const& name, int def);
- float GetFloatDefault(std::string const& name, float def);
-
- std::string const& GetFilename();
- std::list<std::string> GetKeysByString(std::string const& name);
-
-private:
- std::string _filename;
- boost::property_tree::ptree _config;
- std::mutex _configLock;
-
- ConfigMgr(ConfigMgr const&);
- ConfigMgr& operator=(ConfigMgr const&);
-};
-
-#define sConfigMgr ConfigMgr::instance()
-
-#endif
diff --git a/src/server/shared/Debugging/Errors.cpp b/src/server/shared/Debugging/Errors.cpp
deleted file mode 100644
index cebd9d4cf2f..00000000000
--- a/src/server/shared/Debugging/Errors.cpp
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * Copyright (C) 2008-2015 TrinityCore <http://www.trinitycore.org/>
- * 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, see <http://www.gnu.org/licenses/>.
- */
-
-#include "Errors.h"
-
-#include <cstdio>
-#include <cstdlib>
-#include <thread>
-#include <cstdarg>
-
-namespace Trinity {
-
-void Assert(char const* file, int line, char const* function, char const* message)
-{
- fprintf(stderr, "\n%s:%i in %s ASSERTION FAILED:\n %s\n",
- file, line, function, message);
- *((volatile int*)NULL) = 0;
- exit(1);
-}
-
-void Assert(char const* file, int line, char const* function, char const* message, char const* format, ...)
-{
- va_list args;
- va_start(args, format);
-
- fprintf(stderr, "\n%s:%i in %s ASSERTION FAILED:\n %s ", file, line, function, message);
- vfprintf(stderr, format, args);
- fprintf(stderr, "\n");
- fflush(stderr);
-
- va_end(args);
- *((volatile int*)NULL) = 0;
- exit(1);
-}
-
-void Fatal(char const* file, int line, char const* function, char const* message)
-{
- fprintf(stderr, "\n%s:%i in %s FATAL ERROR:\n %s\n",
- file, line, function, message);
-
- std::this_thread::sleep_for(std::chrono::seconds(10));
- *((volatile int*)NULL) = 0;
- exit(1);
-}
-
-void Error(char const* file, int line, char const* function, char const* message)
-{
- fprintf(stderr, "\n%s:%i in %s ERROR:\n %s\n",
- file, line, function, message);
- *((volatile int*)NULL) = 0;
- exit(1);
-}
-
-void Warning(char const* file, int line, char const* function, char const* message)
-{
- fprintf(stderr, "\n%s:%i in %s WARNING:\n %s\n",
- file, line, function, message);
-}
-
-} // namespace Trinity
diff --git a/src/server/shared/Debugging/Errors.h b/src/server/shared/Debugging/Errors.h
deleted file mode 100644
index 4d4624b63dd..00000000000
--- a/src/server/shared/Debugging/Errors.h
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * Copyright (C) 2008-2015 TrinityCore <http://www.trinitycore.org/>
- * 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, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef TRINITYCORE_ERRORS_H
-#define TRINITYCORE_ERRORS_H
-
-#include "Define.h"
-
-namespace Trinity
-{
- DECLSPEC_NORETURN void Assert(char const* file, int line, char const* function, char const* message) ATTR_NORETURN;
- DECLSPEC_NORETURN void Assert(char const* file, int line, char const* function, char const* message, char const* format, ...) ATTR_NORETURN ATTR_PRINTF(5, 6);
-
- DECLSPEC_NORETURN void Fatal(char const* file, int line, char const* function, char const* message) ATTR_NORETURN;
-
- DECLSPEC_NORETURN void Error(char const* file, int line, char const* function, char const* message) ATTR_NORETURN;
-
- void Warning(char const* file, int line, char const* function, char const* message);
-
-} // namespace Trinity
-
-#if COMPILER == COMPILER_MICROSOFT
-#define ASSERT_BEGIN __pragma(warning(push)) __pragma(warning(disable: 4127))
-#define ASSERT_END __pragma(warning(pop))
-#else
-#define ASSERT_BEGIN
-#define ASSERT_END
-#endif
-
-#define WPAssert(cond, ...) ASSERT_BEGIN do { if (!(cond)) Trinity::Assert(__FILE__, __LINE__, __FUNCTION__, #cond, ##__VA_ARGS__); } while(0) ASSERT_END
-#define WPFatal(cond, msg) ASSERT_BEGIN do { if (!(cond)) Trinity::Fatal(__FILE__, __LINE__, __FUNCTION__, (msg)); } while(0) ASSERT_END
-#define WPError(cond, msg) ASSERT_BEGIN do { if (!(cond)) Trinity::Error(__FILE__, __LINE__, __FUNCTION__, (msg)); } while(0) ASSERT_END
-#define WPWarning(cond, msg) ASSERT_BEGIN do { if (!(cond)) Trinity::Warning(__FILE__, __LINE__, __FUNCTION__, (msg)); } while(0) ASSERT_END
-
-#define ASSERT WPAssert
-
-template <typename T> inline T* ASSERT_NOTNULL(T* pointer)
-{
- ASSERT(pointer);
- return pointer;
-}
-
-#endif
diff --git a/src/server/shared/Debugging/WheatyExceptionReport.cpp b/src/server/shared/Debugging/WheatyExceptionReport.cpp
deleted file mode 100644
index 70aa23a8eed..00000000000
--- a/src/server/shared/Debugging/WheatyExceptionReport.cpp
+++ /dev/null
@@ -1,1423 +0,0 @@
-//==========================================
-// Matt Pietrek
-// MSDN Magazine, 2002
-// FILE: WheatyExceptionReport.CPP
-//==========================================
-#include "CompilerDefs.h"
-
-#if PLATFORM == PLATFORM_WINDOWS && !defined(__MINGW32__)
-#define WIN32_LEAN_AND_MEAN
-#pragma warning(disable:4996)
-#pragma warning(disable:4312)
-#pragma warning(disable:4311)
-#include <windows.h>
-#include <tlhelp32.h>
-#include <stdio.h>
-#include <tchar.h>
-#define _NO_CVCONST_H
-#include <dbghelp.h>
-
-#include "WheatyExceptionReport.h"
-
-#include "Common.h"
-#include "Revision.h"
-
-#define CrashFolder _T("Crashes")
-#pragma comment(linker, "/DEFAULTLIB:dbghelp.lib")
-
-inline LPTSTR ErrorMessage(DWORD dw)
-{
- LPVOID lpMsgBuf;
- DWORD formatResult = FormatMessage(
- FORMAT_MESSAGE_ALLOCATE_BUFFER |
- FORMAT_MESSAGE_FROM_SYSTEM,
- NULL,
- dw,
- MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
- (LPTSTR) &lpMsgBuf,
- 0, NULL);
- if (formatResult != 0)
- return (LPTSTR)lpMsgBuf;
- else
- {
- LPTSTR msgBuf = (LPTSTR)LocalAlloc(LPTR, 30);
- sprintf(msgBuf, "Unknown error: %u", dw);
- return msgBuf;
- }
-
-}
-
-//============================== Global Variables =============================
-
-//
-// Declare the static variables of the WheatyExceptionReport class
-//
-TCHAR WheatyExceptionReport::m_szLogFileName[MAX_PATH];
-TCHAR WheatyExceptionReport::m_szDumpFileName[MAX_PATH];
-LPTOP_LEVEL_EXCEPTION_FILTER WheatyExceptionReport::m_previousFilter;
-HANDLE WheatyExceptionReport::m_hReportFile;
-HANDLE WheatyExceptionReport::m_hDumpFile;
-HANDLE WheatyExceptionReport::m_hProcess;
-SymbolPairs WheatyExceptionReport::symbols;
-std::stack<SymbolDetail> WheatyExceptionReport::symbolDetails;
-bool WheatyExceptionReport::stackOverflowException;
-bool WheatyExceptionReport::alreadyCrashed;
-std::mutex WheatyExceptionReport::alreadyCrashedLock;
-
-// Declare global instance of class
-WheatyExceptionReport g_WheatyExceptionReport;
-
-//============================== Class Methods =============================
-
-WheatyExceptionReport::WheatyExceptionReport() // Constructor
-{
- // Install the unhandled exception filter function
- m_previousFilter = SetUnhandledExceptionFilter(WheatyUnhandledExceptionFilter);
- m_hProcess = GetCurrentProcess();
- stackOverflowException = false;
- alreadyCrashed = false;
- if (!IsDebuggerPresent())
- {
- _CrtSetReportMode(_CRT_ERROR, _CRTDBG_MODE_FILE);
- _CrtSetReportFile(_CRT_ERROR, _CRTDBG_FILE_STDERR);
- _CrtSetReportMode(_CRT_ASSERT, _CRTDBG_MODE_FILE);
- _CrtSetReportFile(_CRT_ASSERT, _CRTDBG_FILE_STDERR);
- }
-}
-
-//============
-// Destructor
-//============
-WheatyExceptionReport::~WheatyExceptionReport()
-{
- if (m_previousFilter)
- SetUnhandledExceptionFilter(m_previousFilter);
- ClearSymbols();
-}
-
-//===========================================================
-// Entry point where control comes on an unhandled exception
-//===========================================================
-LONG WINAPI WheatyExceptionReport::WheatyUnhandledExceptionFilter(
-PEXCEPTION_POINTERS pExceptionInfo)
-{
- std::unique_lock<std::mutex> guard(alreadyCrashedLock);
- // Handle only 1 exception in the whole process lifetime
- if (alreadyCrashed)
- return EXCEPTION_EXECUTE_HANDLER;
-
- alreadyCrashed = true;
-
- if (pExceptionInfo->ExceptionRecord->ExceptionCode == STATUS_STACK_OVERFLOW)
- stackOverflowException = true;
-
- TCHAR module_folder_name[MAX_PATH];
- GetModuleFileName(0, module_folder_name, MAX_PATH);
- TCHAR* pos = _tcsrchr(module_folder_name, '\\');
- if (!pos)
- return 0;
- pos[0] = '\0';
- ++pos;
-
- TCHAR crash_folder_path[MAX_PATH];
- sprintf(crash_folder_path, "%s\\%s", module_folder_name, CrashFolder);
- if (!CreateDirectory(crash_folder_path, NULL))
- {
- if (GetLastError() != ERROR_ALREADY_EXISTS)
- return 0;
- }
-
- SYSTEMTIME systime;
- GetLocalTime(&systime);
- sprintf(m_szDumpFileName, "%s\\%s_%s_[%u-%u_%u-%u-%u].dmp",
- crash_folder_path, Revision::GetHash(), pos, systime.wDay, systime.wMonth, systime.wHour, systime.wMinute, systime.wSecond);
-
- sprintf(m_szLogFileName, "%s\\%s_%s_[%u-%u_%u-%u-%u].txt",
- crash_folder_path, Revision::GetHash(), pos, systime.wDay, systime.wMonth, systime.wHour, systime.wMinute, systime.wSecond);
-
- m_hDumpFile = CreateFile(m_szDumpFileName,
- GENERIC_WRITE,
- 0,
- 0,
- OPEN_ALWAYS,
- FILE_FLAG_WRITE_THROUGH,
- 0);
-
- m_hReportFile = CreateFile(m_szLogFileName,
- GENERIC_WRITE,
- 0,
- 0,
- OPEN_ALWAYS,
- FILE_FLAG_WRITE_THROUGH,
- 0);
-
- if (m_hDumpFile)
- {
- MINIDUMP_EXCEPTION_INFORMATION info;
- info.ClientPointers = FALSE;
- info.ExceptionPointers = pExceptionInfo;
- info.ThreadId = GetCurrentThreadId();
-
- MiniDumpWriteDump(GetCurrentProcess(), GetCurrentProcessId(),
- m_hDumpFile, MiniDumpWithIndirectlyReferencedMemory, &info, 0, 0);
-
- CloseHandle(m_hDumpFile);
- }
-
- if (m_hReportFile)
- {
- SetFilePointer(m_hReportFile, 0, 0, FILE_END);
-
- GenerateExceptionReport(pExceptionInfo);
-
- CloseHandle(m_hReportFile);
- m_hReportFile = 0;
- }
-
- if (m_previousFilter)
- return m_previousFilter(pExceptionInfo);
- else
- return EXCEPTION_EXECUTE_HANDLER/*EXCEPTION_CONTINUE_SEARCH*/;
-}
-
-BOOL WheatyExceptionReport::_GetProcessorName(TCHAR* sProcessorName, DWORD maxcount)
-{
- if (!sProcessorName)
- return FALSE;
-
- HKEY hKey;
- LONG lRet;
- lRet = ::RegOpenKeyEx(HKEY_LOCAL_MACHINE, _T("HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\0"),
- 0, KEY_QUERY_VALUE, &hKey);
- if (lRet != ERROR_SUCCESS)
- return FALSE;
- TCHAR szTmp[2048];
- DWORD cntBytes = sizeof(szTmp);
- lRet = ::RegQueryValueEx(hKey, _T("ProcessorNameString"), NULL, NULL,
- (LPBYTE)szTmp, &cntBytes);
- if (lRet != ERROR_SUCCESS)
- return FALSE;
- ::RegCloseKey(hKey);
- sProcessorName[0] = '\0';
- // Skip spaces
- TCHAR* psz = szTmp;
- while (iswspace(*psz))
- ++psz;
- _tcsncpy(sProcessorName, psz, maxcount);
- return TRUE;
-}
-
-BOOL WheatyExceptionReport::_GetWindowsVersion(TCHAR* szVersion, DWORD cntMax)
-{
- // Try calling GetVersionEx using the OSVERSIONINFOEX structure.
- // If that fails, try using the OSVERSIONINFO structure.
- OSVERSIONINFOEX osvi = { 0 };
- osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
- BOOL bOsVersionInfoEx;
- bOsVersionInfoEx = ::GetVersionEx((LPOSVERSIONINFO)(&osvi));
- if (!bOsVersionInfoEx)
- {
- osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
- if (!::GetVersionEx((OSVERSIONINFO*)&osvi))
- return FALSE;
- }
- *szVersion = _T('\0');
- TCHAR wszTmp[128];
- switch (osvi.dwPlatformId)
- {
- // Windows NT product family.
- case VER_PLATFORM_WIN32_NT:
- {
- #if WINVER < 0x0500
- BYTE suiteMask = osvi.wReserved[0];
- BYTE productType = osvi.wReserved[1];
- #else
- WORD suiteMask = osvi.wSuiteMask;
- BYTE productType = osvi.wProductType;
- #endif // WINVER < 0x0500
-
- // Test for the specific product family.
- if (osvi.dwMajorVersion == 6)
- {
- if (productType == VER_NT_WORKSTATION)
- {
- if (osvi.dwMinorVersion == 2)
- _tcsncat(szVersion, _T("Windows 8 "), cntMax);
- else if (osvi.dwMinorVersion == 1)
- _tcsncat(szVersion, _T("Windows 7 "), cntMax);
- else
- _tcsncat(szVersion, _T("Windows Vista "), cntMax);
- }
- else if (osvi.dwMinorVersion == 2)
- _tcsncat(szVersion, _T("Windows Server 2012 "), cntMax);
- else if (osvi.dwMinorVersion == 1)
- _tcsncat(szVersion, _T("Windows Server 2008 R2 "), cntMax);
- else
- _tcsncat(szVersion, _T("Windows Server 2008 "), cntMax);
- }
- else if (osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 2)
- _tcsncat(szVersion, _T("Microsoft Windows Server 2003 "), cntMax);
- else if (osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 1)
- _tcsncat(szVersion, _T("Microsoft Windows XP "), cntMax);
- else if (osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 0)
- _tcsncat(szVersion, _T("Microsoft Windows 2000 "), cntMax);
- else if (osvi.dwMajorVersion <= 4)
- _tcsncat(szVersion, _T("Microsoft Windows NT "), cntMax);
-
- // Test for specific product on Windows NT 4.0 SP6 and later.
- if (bOsVersionInfoEx)
- {
- // Test for the workstation type.
- if (productType == VER_NT_WORKSTATION)
- {
- if (osvi.dwMajorVersion == 4)
- _tcsncat(szVersion, _T("Workstation 4.0 "), cntMax);
- else if (suiteMask & VER_SUITE_PERSONAL)
- _tcsncat(szVersion, _T("Home Edition "), cntMax);
- else if (suiteMask & VER_SUITE_EMBEDDEDNT)
- _tcsncat(szVersion, _T("Embedded "), cntMax);
- else
- _tcsncat(szVersion, _T("Professional "), cntMax);
- }
- // Test for the server type.
- else if (productType == VER_NT_SERVER)
- {
- if (osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 2)
- {
- if (suiteMask & VER_SUITE_DATACENTER)
- _tcsncat(szVersion, _T("Datacenter Edition "), cntMax);
- else if (suiteMask & VER_SUITE_ENTERPRISE)
- _tcsncat(szVersion, _T("Enterprise Edition "), cntMax);
- else if (suiteMask == VER_SUITE_BLADE)
- _tcsncat(szVersion, _T("Web Edition "), cntMax);
- else
- _tcsncat(szVersion, _T("Standard Edition "), cntMax);
- }
- else if (osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 0)
- {
- if (suiteMask & VER_SUITE_DATACENTER)
- _tcsncat(szVersion, _T("Datacenter Server "), cntMax);
- else if (suiteMask & VER_SUITE_ENTERPRISE)
- _tcsncat(szVersion, _T("Advanced Server "), cntMax);
- else
- _tcsncat(szVersion, _T("Server "), cntMax);
- }
- else // Windows NT 4.0
- {
- if (suiteMask & VER_SUITE_ENTERPRISE)
- _tcsncat(szVersion, _T("Server 4.0, Enterprise Edition "), cntMax);
- else
- _tcsncat(szVersion, _T("Server 4.0 "), cntMax);
- }
- }
- }
-
- // Display service pack (if any) and build number.
- if (osvi.dwMajorVersion == 4 && _tcsicmp(osvi.szCSDVersion, _T("Service Pack 6")) == 0)
- {
- HKEY hKey;
- LONG lRet;
-
- // Test for SP6 versus SP6a.
- lRet = ::RegOpenKeyEx(HKEY_LOCAL_MACHINE, _T("SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Hotfix\\Q246009"), 0, KEY_QUERY_VALUE, &hKey);
- if (lRet == ERROR_SUCCESS)
- {
- _stprintf(wszTmp, _T("Service Pack 6a (Version %d.%d, Build %d)"),
- osvi.dwMajorVersion, osvi.dwMinorVersion, osvi.dwBuildNumber & 0xFFFF);
- _tcsncat(szVersion, wszTmp, cntMax);
- }
- else // Windows NT 4.0 prior to SP6a
- {
- _stprintf(wszTmp, _T("%s (Version %d.%d, Build %d)"),
- osvi.szCSDVersion, osvi.dwMajorVersion, osvi.dwMinorVersion, osvi.dwBuildNumber & 0xFFFF);
- _tcsncat(szVersion, wszTmp, cntMax);
- }
- ::RegCloseKey(hKey);
- }
- else // Windows NT 3.51 and earlier or Windows 2000 and later
- {
- if (!_tcslen(osvi.szCSDVersion))
- _stprintf(wszTmp, _T("(Version %d.%d, Build %d)"),
- osvi.dwMajorVersion, osvi.dwMinorVersion, osvi.dwBuildNumber & 0xFFFF);
- else
- _stprintf(wszTmp, _T("%s (Version %d.%d, Build %d)"),
- osvi.szCSDVersion, osvi.dwMajorVersion, osvi.dwMinorVersion, osvi.dwBuildNumber & 0xFFFF);
- _tcsncat(szVersion, wszTmp, cntMax);
- }
- break;
- }
- default:
- _stprintf(wszTmp, _T("%s (Version %d.%d, Build %d)"),
- osvi.szCSDVersion, osvi.dwMajorVersion, osvi.dwMinorVersion, osvi.dwBuildNumber & 0xFFFF);
- _tcsncat(szVersion, wszTmp, cntMax);
- break;
- }
-
- return TRUE;
-}
-
-void WheatyExceptionReport::PrintSystemInfo()
-{
- SYSTEM_INFO SystemInfo;
- ::GetSystemInfo(&SystemInfo);
-
- MEMORYSTATUS MemoryStatus;
- MemoryStatus.dwLength = sizeof (MEMORYSTATUS);
- ::GlobalMemoryStatus(&MemoryStatus);
- TCHAR sString[1024];
- _tprintf(_T("//=====================================================\r\n"));
- if (_GetProcessorName(sString, countof(sString)))
- _tprintf(_T("*** Hardware ***\r\nProcessor: %s\r\nNumber Of Processors: %d\r\nPhysical Memory: %d KB (Available: %d KB)\r\nCommit Charge Limit: %d KB\r\n"),
- sString, SystemInfo.dwNumberOfProcessors, MemoryStatus.dwTotalPhys/0x400, MemoryStatus.dwAvailPhys/0x400, MemoryStatus.dwTotalPageFile/0x400);
- else
- _tprintf(_T("*** Hardware ***\r\nProcessor: <unknown>\r\nNumber Of Processors: %d\r\nPhysical Memory: %d KB (Available: %d KB)\r\nCommit Charge Limit: %d KB\r\n"),
- SystemInfo.dwNumberOfProcessors, MemoryStatus.dwTotalPhys/0x400, MemoryStatus.dwAvailPhys/0x400, MemoryStatus.dwTotalPageFile/0x400);
-
- if (_GetWindowsVersion(sString, countof(sString)))
- _tprintf(_T("\r\n*** Operation System ***\r\n%s\r\n"), sString);
- else
- _tprintf(_T("\r\n*** Operation System:\r\n<unknown>\r\n"));
-}
-
-//===========================================================================
-void WheatyExceptionReport::printTracesForAllThreads(bool bWriteVariables)
-{
- THREADENTRY32 te32;
-
- DWORD dwOwnerPID = GetCurrentProcessId();
- m_hProcess = GetCurrentProcess();
- // Take a snapshot of all running threads
- HANDLE hThreadSnap = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0);
- if (hThreadSnap == INVALID_HANDLE_VALUE)
- return;
-
- // Fill in the size of the structure before using it.
- te32.dwSize = sizeof(THREADENTRY32);
-
- // Retrieve information about the first thread,
- // and exit if unsuccessful
- if (!Thread32First(hThreadSnap, &te32))
- {
- CloseHandle(hThreadSnap); // Must clean up the
- // snapshot object!
- return;
- }
-
- // Now walk the thread list of the system,
- // and display information about each thread
- // associated with the specified process
- do
- {
- if (te32.th32OwnerProcessID == dwOwnerPID)
- {
- CONTEXT context;
- context.ContextFlags = 0xffffffff;
- HANDLE threadHandle = OpenThread(THREAD_GET_CONTEXT | THREAD_QUERY_INFORMATION, false, te32.th32ThreadID);
- if (threadHandle)
- {
- if (GetThreadContext(threadHandle, &context))
- WriteStackDetails(&context, bWriteVariables, threadHandle);
- CloseHandle(threadHandle);
- }
- }
- } while (Thread32Next(hThreadSnap, &te32));
-
-// Don't forget to clean up the snapshot object.
- CloseHandle(hThreadSnap);
-}
-
-//===========================================================================
-// Open the report file, and write the desired information to it. Called by
-// WheatyUnhandledExceptionFilter
-//===========================================================================
-void WheatyExceptionReport::GenerateExceptionReport(
-PEXCEPTION_POINTERS pExceptionInfo)
-{
- __try
- {
- SYSTEMTIME systime;
- GetLocalTime(&systime);
-
- // Start out with a banner
- _tprintf(_T("Revision: %s\r\n"), Revision::GetFullVersion());
- _tprintf(_T("Date %u:%u:%u. Time %u:%u \r\n"), systime.wDay, systime.wMonth, systime.wYear, systime.wHour, systime.wMinute);
- PEXCEPTION_RECORD pExceptionRecord = pExceptionInfo->ExceptionRecord;
-
- PrintSystemInfo();
- // First print information about the type of fault
- _tprintf(_T("\r\n//=====================================================\r\n"));
- _tprintf(_T("Exception code: %08X %s\r\n"),
- pExceptionRecord->ExceptionCode,
- GetExceptionString(pExceptionRecord->ExceptionCode));
-
- // Now print information about where the fault occured
- TCHAR szFaultingModule[MAX_PATH];
- DWORD section;
- DWORD_PTR offset;
- GetLogicalAddress(pExceptionRecord->ExceptionAddress,
- szFaultingModule,
- sizeof(szFaultingModule),
- section, offset);
-
-#ifdef _M_IX86
- _tprintf(_T("Fault address: %08X %02X:%08X %s\r\n"),
- pExceptionRecord->ExceptionAddress,
- section, offset, szFaultingModule);
-#endif
-#ifdef _M_X64
- _tprintf(_T("Fault address: %016I64X %02X:%016I64X %s\r\n"),
- pExceptionRecord->ExceptionAddress,
- section, offset, szFaultingModule);
-#endif
-
- PCONTEXT pCtx = pExceptionInfo->ContextRecord;
-
- // Show the registers
-#ifdef _M_IX86 // X86 Only!
- _tprintf(_T("\r\nRegisters:\r\n"));
-
- _tprintf(_T("EAX:%08X\r\nEBX:%08X\r\nECX:%08X\r\nEDX:%08X\r\nESI:%08X\r\nEDI:%08X\r\n")
- , pCtx->Eax, pCtx->Ebx, pCtx->Ecx, pCtx->Edx,
- pCtx->Esi, pCtx->Edi);
-
- _tprintf(_T("CS:EIP:%04X:%08X\r\n"), pCtx->SegCs, pCtx->Eip);
- _tprintf(_T("SS:ESP:%04X:%08X EBP:%08X\r\n"),
- pCtx->SegSs, pCtx->Esp, pCtx->Ebp);
- _tprintf(_T("DS:%04X ES:%04X FS:%04X GS:%04X\r\n"),
- pCtx->SegDs, pCtx->SegEs, pCtx->SegFs, pCtx->SegGs);
- _tprintf(_T("Flags:%08X\r\n"), pCtx->EFlags);
-#endif
-
-#ifdef _M_X64
- _tprintf(_T("\r\nRegisters:\r\n"));
- _tprintf(_T("RAX:%016I64X\r\nRBX:%016I64X\r\nRCX:%016I64X\r\nRDX:%016I64X\r\nRSI:%016I64X\r\nRDI:%016I64X\r\n")
- _T("R8: %016I64X\r\nR9: %016I64X\r\nR10:%016I64X\r\nR11:%016I64X\r\nR12:%016I64X\r\nR13:%016I64X\r\nR14:%016I64X\r\nR15:%016I64X\r\n")
- , pCtx->Rax, pCtx->Rbx, pCtx->Rcx, pCtx->Rdx,
- pCtx->Rsi, pCtx->Rdi, pCtx->R9, pCtx->R10, pCtx->R11, pCtx->R12, pCtx->R13, pCtx->R14, pCtx->R15);
- _tprintf(_T("CS:RIP:%04X:%016I64X\r\n"), pCtx->SegCs, pCtx->Rip);
- _tprintf(_T("SS:RSP:%04X:%016X RBP:%08X\r\n"),
- pCtx->SegSs, pCtx->Rsp, pCtx->Rbp);
- _tprintf(_T("DS:%04X ES:%04X FS:%04X GS:%04X\r\n"),
- pCtx->SegDs, pCtx->SegEs, pCtx->SegFs, pCtx->SegGs);
- _tprintf(_T("Flags:%08X\r\n"), pCtx->EFlags);
-#endif
-
- SymSetOptions(SYMOPT_DEFERRED_LOADS);
-
- // Initialize DbgHelp
- if (!SymInitialize(GetCurrentProcess(), 0, TRUE))
- {
- _tprintf(_T("\n\rCRITICAL ERROR.\n\r Couldn't initialize the symbol handler for process.\n\rError [%s].\n\r\n\r"),
- ErrorMessage(GetLastError()));
- }
-
- CONTEXT trashableContext = *pCtx;
-
- WriteStackDetails(&trashableContext, false, NULL);
- printTracesForAllThreads(false);
-
- // #ifdef _M_IX86 // X86 Only!
-
- _tprintf(_T("========================\r\n"));
- _tprintf(_T("Local Variables And Parameters\r\n"));
-
- trashableContext = *pCtx;
- WriteStackDetails(&trashableContext, true, NULL);
- printTracesForAllThreads(true);
-
- /*_tprintf(_T("========================\r\n"));
- _tprintf(_T("Global Variables\r\n"));
-
- SymEnumSymbols(GetCurrentProcess(),
- (UINT_PTR)GetModuleHandle(szFaultingModule),
- 0, EnumerateSymbolsCallback, 0);*/
- // #endif // X86 Only!
-
- SymCleanup(GetCurrentProcess());
-
- _tprintf(_T("\r\n"));
- }
- __except (EXCEPTION_EXECUTE_HANDLER)
- {
- _tprintf(_T("Error writing the crash log\r\n"));
- }
-}
-
-//======================================================================
-// Given an exception code, returns a pointer to a static string with a
-// description of the exception
-//======================================================================
-LPTSTR WheatyExceptionReport::GetExceptionString(DWORD dwCode)
-{
- #define EXCEPTION(x) case EXCEPTION_##x: return _T(#x);
-
- switch (dwCode)
- {
- EXCEPTION(ACCESS_VIOLATION)
- EXCEPTION(DATATYPE_MISALIGNMENT)
- EXCEPTION(BREAKPOINT)
- EXCEPTION(SINGLE_STEP)
- EXCEPTION(ARRAY_BOUNDS_EXCEEDED)
- EXCEPTION(FLT_DENORMAL_OPERAND)
- EXCEPTION(FLT_DIVIDE_BY_ZERO)
- EXCEPTION(FLT_INEXACT_RESULT)
- EXCEPTION(FLT_INVALID_OPERATION)
- EXCEPTION(FLT_OVERFLOW)
- EXCEPTION(FLT_STACK_CHECK)
- EXCEPTION(FLT_UNDERFLOW)
- EXCEPTION(INT_DIVIDE_BY_ZERO)
- EXCEPTION(INT_OVERFLOW)
- EXCEPTION(PRIV_INSTRUCTION)
- EXCEPTION(IN_PAGE_ERROR)
- EXCEPTION(ILLEGAL_INSTRUCTION)
- EXCEPTION(NONCONTINUABLE_EXCEPTION)
- EXCEPTION(STACK_OVERFLOW)
- EXCEPTION(INVALID_DISPOSITION)
- EXCEPTION(GUARD_PAGE)
- EXCEPTION(INVALID_HANDLE)
- }
-
- // If not one of the "known" exceptions, try to get the string
- // from NTDLL.DLL's message table.
-
- static TCHAR szBuffer[512] = { 0 };
-
- FormatMessage(FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_FROM_HMODULE,
- GetModuleHandle(_T("NTDLL.DLL")),
- dwCode, 0, szBuffer, sizeof(szBuffer), 0);
-
- return szBuffer;
-}
-
-//=============================================================================
-// Given a linear address, locates the module, section, and offset containing
-// that address.
-//
-// Note: the szModule paramater buffer is an output buffer of length specified
-// by the len parameter (in characters!)
-//=============================================================================
-BOOL WheatyExceptionReport::GetLogicalAddress(
-PVOID addr, PTSTR szModule, DWORD len, DWORD& section, DWORD_PTR& offset)
-{
- MEMORY_BASIC_INFORMATION mbi;
-
- if (!VirtualQuery(addr, &mbi, sizeof(mbi)))
- return FALSE;
-
- DWORD_PTR hMod = (DWORD_PTR)mbi.AllocationBase;
-
- if (!hMod)
- return FALSE;
-
- if (!GetModuleFileName((HMODULE)hMod, szModule, len))
- return FALSE;
-
- // Point to the DOS header in memory
- PIMAGE_DOS_HEADER pDosHdr = (PIMAGE_DOS_HEADER)hMod;
-
- // From the DOS header, find the NT (PE) header
- PIMAGE_NT_HEADERS pNtHdr = (PIMAGE_NT_HEADERS)(hMod + DWORD_PTR(pDosHdr->e_lfanew));
-
- PIMAGE_SECTION_HEADER pSection = IMAGE_FIRST_SECTION(pNtHdr);
-
- DWORD_PTR rva = (DWORD_PTR)addr - hMod; // RVA is offset from module load address
-
- // Iterate through the section table, looking for the one that encompasses
- // the linear address.
- for (unsigned i = 0;
- i < pNtHdr->FileHeader.NumberOfSections;
- i++, pSection++)
- {
- DWORD_PTR sectionStart = pSection->VirtualAddress;
- DWORD_PTR sectionEnd = sectionStart
- + DWORD_PTR(std::max(pSection->SizeOfRawData, pSection->Misc.VirtualSize));
-
- // Is the address in this section???
- if ((rva >= sectionStart) && (rva <= sectionEnd))
- {
- // Yes, address is in the section. Calculate section and offset,
- // and store in the "section" & "offset" params, which were
- // passed by reference.
- section = i+1;
- offset = rva - sectionStart;
- return TRUE;
- }
- }
-
- return FALSE; // Should never get here!
-}
-
-// It contains SYMBOL_INFO structure plus additional
-// space for the name of the symbol
-struct CSymbolInfoPackage : public SYMBOL_INFO_PACKAGE
-{
- CSymbolInfoPackage()
- {
- si.SizeOfStruct = sizeof(SYMBOL_INFO);
- si.MaxNameLen = sizeof(name);
- }
-};
-
-//============================================================
-// Walks the stack, and writes the results to the report file
-//============================================================
-void WheatyExceptionReport::WriteStackDetails(
-PCONTEXT pContext,
-bool bWriteVariables, HANDLE pThreadHandle) // true if local/params should be output
-{
- _tprintf(_T("\r\nCall stack:\r\n"));
-
- _tprintf(_T("Address Frame Function SourceFile\r\n"));
-
- DWORD dwMachineType = 0;
- // Could use SymSetOptions here to add the SYMOPT_DEFERRED_LOADS flag
-
- STACKFRAME64 sf;
- memset(&sf, 0, sizeof(sf));
-
- #ifdef _M_IX86
- // Initialize the STACKFRAME structure for the first call. This is only
- // necessary for Intel CPUs, and isn't mentioned in the documentation.
- sf.AddrPC.Offset = pContext->Eip;
- sf.AddrPC.Mode = AddrModeFlat;
- sf.AddrStack.Offset = pContext->Esp;
- sf.AddrStack.Mode = AddrModeFlat;
- sf.AddrFrame.Offset = pContext->Ebp;
- sf.AddrFrame.Mode = AddrModeFlat;
-
- dwMachineType = IMAGE_FILE_MACHINE_I386;
- #endif
-
-#ifdef _M_X64
- sf.AddrPC.Offset = pContext->Rip;
- sf.AddrPC.Mode = AddrModeFlat;
- sf.AddrStack.Offset = pContext->Rsp;
- sf.AddrStack.Mode = AddrModeFlat;
- sf.AddrFrame.Offset = pContext->Rbp;
- sf.AddrFrame.Mode = AddrModeFlat;
- dwMachineType = IMAGE_FILE_MACHINE_AMD64;
-#endif
-
- for (;;)
- {
- // Get the next stack frame
- if (! StackWalk64(dwMachineType,
- m_hProcess,
- pThreadHandle != NULL ? pThreadHandle : GetCurrentThread(),
- &sf,
- pContext,
- 0,
- SymFunctionTableAccess64,
- SymGetModuleBase64,
- 0))
- break;
- if (0 == sf.AddrFrame.Offset) // Basic sanity check to make sure
- break; // the frame is OK. Bail if not.
-#ifdef _M_IX86
- _tprintf(_T("%08X %08X "), sf.AddrPC.Offset, sf.AddrFrame.Offset);
-#endif
-#ifdef _M_X64
- _tprintf(_T("%016I64X %016I64X "), sf.AddrPC.Offset, sf.AddrFrame.Offset);
-#endif
-
- DWORD64 symDisplacement = 0; // Displacement of the input address,
- // relative to the start of the symbol
-
- // Get the name of the function for this stack frame entry
- CSymbolInfoPackage sip;
- if (SymFromAddr(
- m_hProcess, // Process handle of the current process
- sf.AddrPC.Offset, // Symbol address
- &symDisplacement, // Address of the variable that will receive the displacement
- &sip.si)) // Address of the SYMBOL_INFO structure (inside "sip" object)
- {
- _tprintf(_T("%hs+%I64X"), sip.si.Name, symDisplacement);
-
- }
- else // No symbol found. Print out the logical address instead.
- {
- TCHAR szModule[MAX_PATH] = _T("");
- DWORD section = 0;
- DWORD_PTR offset = 0;
-
- GetLogicalAddress((PVOID)sf.AddrPC.Offset,
- szModule, sizeof(szModule), section, offset);
-#ifdef _M_IX86
- _tprintf(_T("%04X:%08X %s"), section, offset, szModule);
-#endif
-#ifdef _M_X64
- _tprintf(_T("%04X:%016I64X %s"), section, offset, szModule);
-#endif
- }
-
- // Get the source line for this stack frame entry
- IMAGEHLP_LINE64 lineInfo = { sizeof(IMAGEHLP_LINE64) };
- DWORD dwLineDisplacement;
- if (SymGetLineFromAddr64(m_hProcess, sf.AddrPC.Offset,
- &dwLineDisplacement, &lineInfo))
- {
- _tprintf(_T(" %s line %u"), lineInfo.FileName, lineInfo.LineNumber);
- }
-
- _tprintf(_T("\r\n"));
-
- // Write out the variables, if desired
- if (bWriteVariables)
- {
- // Use SymSetContext to get just the locals/params for this frame
- IMAGEHLP_STACK_FRAME imagehlpStackFrame;
- imagehlpStackFrame.InstructionOffset = sf.AddrPC.Offset;
- SymSetContext(m_hProcess, &imagehlpStackFrame, 0);
-
- // Enumerate the locals/parameters
- SymEnumSymbols(m_hProcess, 0, 0, EnumerateSymbolsCallback, &sf);
-
- _tprintf(_T("\r\n"));
- }
- }
-
-}
-
-//////////////////////////////////////////////////////////////////////////////
-// The function invoked by SymEnumSymbols
-//////////////////////////////////////////////////////////////////////////////
-
-BOOL CALLBACK
-WheatyExceptionReport::EnumerateSymbolsCallback(
-PSYMBOL_INFO pSymInfo,
-ULONG /*SymbolSize*/,
-PVOID UserContext)
-{
-
- char szBuffer[WER_LARGE_BUFFER_SIZE];
- memset(szBuffer, 0, sizeof(szBuffer));
-
- __try
- {
- ClearSymbols();
- if (FormatSymbolValue(pSymInfo, (STACKFRAME64*)UserContext,
- szBuffer, sizeof(szBuffer)))
- _tprintf(_T("%s"), szBuffer);
- }
- __except (EXCEPTION_EXECUTE_HANDLER)
- {
- _tprintf(_T("punting on symbol %s, partial output:\r\n"), pSymInfo->Name);
- if (szBuffer[0] != '\0')
- _tprintf(_T("%s"), szBuffer);
- }
-
- return TRUE;
-}
-
-//////////////////////////////////////////////////////////////////////////////
-// Given a SYMBOL_INFO representing a particular variable, displays its
-// contents. If it's a user defined type, display the members and their
-// values.
-//////////////////////////////////////////////////////////////////////////////
-bool WheatyExceptionReport::FormatSymbolValue(
-PSYMBOL_INFO pSym,
-STACKFRAME64 * sf,
-char * pszBuffer,
-unsigned /*cbBuffer*/)
-{
- char * pszCurrBuffer = pszBuffer;
-
- // If it's a function, don't do anything.
- if (pSym->Tag == SymTagFunction) // SymTagFunction from CVCONST.H from the DIA SDK
- return false;
-
- DWORD_PTR pVariable = 0; // Will point to the variable's data in memory
-
- if (pSym->Flags & IMAGEHLP_SYMBOL_INFO_REGRELATIVE)
- {
- // if (pSym->Register == 8) // EBP is the value 8 (in DBGHELP 5.1)
- { // This may change!!!
-#ifdef _M_IX86
- pVariable = sf->AddrFrame.Offset;
-#elif _M_X64
- pVariable = sf->AddrStack.Offset;
-#endif
- pVariable += (DWORD_PTR)pSym->Address;
- }
- // else
- // return false;
- }
- else if (pSym->Flags & IMAGEHLP_SYMBOL_INFO_REGISTER)
- return false; // Don't try to report register variable
- else
- {
- pVariable = (DWORD_PTR)pSym->Address; // It must be a global variable
- }
-
- pszCurrBuffer = PushSymbolDetail(pszCurrBuffer);
-
- // Indicate if the variable is a local or parameter
- if (pSym->Flags & IMAGEHLP_SYMBOL_INFO_PARAMETER)
- symbolDetails.top().Prefix = "Parameter ";
- else if (pSym->Flags & IMAGEHLP_SYMBOL_INFO_LOCAL)
- symbolDetails.top().Prefix = "Local ";
-
- // Determine if the variable is a user defined type (UDT). IF so, bHandled
- // will return true.
- bool bHandled;
- pszCurrBuffer = DumpTypeIndex(pszCurrBuffer, pSym->ModBase, pSym->TypeIndex,
- 0, pVariable, bHandled, pSym->Name, "", false, true);
-
- if (!bHandled)
- {
- // The symbol wasn't a UDT, so do basic, stupid formatting of the
- // variable. Based on the size, we're assuming it's a char, WORD, or
- // DWORD.
- BasicType basicType = GetBasicType(pSym->TypeIndex, pSym->ModBase);
- if (symbolDetails.top().Type.empty())
- symbolDetails.top().Type = rgBaseType[basicType];
-
- // Emit the variable name
- if (pSym->Name[0] != '\0')
- symbolDetails.top().Name = pSym->Name;
-
- char buffer[50];
- FormatOutputValue(buffer, basicType, pSym->Size, (PVOID)pVariable, sizeof(buffer));
- symbolDetails.top().Value = buffer;
- }
-
- pszCurrBuffer = PopSymbolDetail(pszCurrBuffer);
- return true;
-}
-
-//////////////////////////////////////////////////////////////////////////////
-// If it's a user defined type (UDT), recurse through its members until we're
-// at fundamental types. When he hit fundamental types, return
-// bHandled = false, so that FormatSymbolValue() will format them.
-//////////////////////////////////////////////////////////////////////////////
-char * WheatyExceptionReport::DumpTypeIndex(
-char * pszCurrBuffer,
-DWORD64 modBase,
-DWORD dwTypeIndex,
-unsigned nestingLevel,
-DWORD_PTR offset,
-bool & bHandled,
-const char* Name,
-char* /*suffix*/,
-bool newSymbol,
-bool logChildren)
-{
- bHandled = false;
-
- if (newSymbol)
- pszCurrBuffer = PushSymbolDetail(pszCurrBuffer);
-
- DWORD typeTag;
- if (!SymGetTypeInfo(m_hProcess, modBase, dwTypeIndex, TI_GET_SYMTAG, &typeTag))
- return pszCurrBuffer;
-
- // Get the name of the symbol. This will either be a Type name (if a UDT),
- // or the structure member name.
- WCHAR * pwszTypeName;
- if (SymGetTypeInfo(m_hProcess, modBase, dwTypeIndex, TI_GET_SYMNAME,
- &pwszTypeName))
- {
- // handle special cases
- if (wcscmp(pwszTypeName, L"std::basic_string<char,std::char_traits<char>,std::allocator<char> >") == 0)
- {
- LocalFree(pwszTypeName);
- symbolDetails.top().Type = "std::string";
- char buffer[50];
- FormatOutputValue(buffer, btStdString, 0, (PVOID)offset, sizeof(buffer));
- symbolDetails.top().Value = buffer;
- if (Name != NULL && Name[0] != '\0')
- symbolDetails.top().Name = Name;
- bHandled = true;
- return pszCurrBuffer;
- }
-
- char buffer[200];
- wcstombs(buffer, pwszTypeName, sizeof(buffer));
- buffer[199] = '\0';
- if (Name != NULL && Name[0] != '\0')
- {
- symbolDetails.top().Type = buffer;
- symbolDetails.top().Name = Name;
- }
- else if (buffer[0] != '\0')
- symbolDetails.top().Name = buffer;
-
- LocalFree(pwszTypeName);
- }
- else if (Name != NULL && Name[0] != '\0')
- symbolDetails.top().Name = Name;
-
- if (!StoreSymbol(dwTypeIndex, offset))
- {
- // Skip printing address and base class if it has been printed already
- if (typeTag == SymTagBaseClass)
- bHandled = true;
- return pszCurrBuffer;
- }
-
- DWORD innerTypeID;
- switch (typeTag)
- {
- case SymTagPointerType:
- if (SymGetTypeInfo(m_hProcess, modBase, dwTypeIndex, TI_GET_TYPEID, &innerTypeID))
- {
- if (Name != NULL && Name[0] != '\0')
- symbolDetails.top().Name = Name;
-
- BOOL isReference;
- SymGetTypeInfo(m_hProcess, modBase, dwTypeIndex, TI_GET_IS_REFERENCE, &isReference);
-
- char addressStr[40];
- memset(addressStr, 0, sizeof(addressStr));
-
- if (isReference)
- symbolDetails.top().Suffix += "&";
- else
- symbolDetails.top().Suffix += "*";
-
- // Try to dereference the pointer in a try/except block since it might be invalid
- DWORD_PTR address = DereferenceUnsafePointer(offset);
-
- char buffer[50];
- FormatOutputValue(buffer, btVoid, sizeof(PVOID), (PVOID)offset, sizeof(buffer));
- symbolDetails.top().Value = buffer;
-
- if (nestingLevel >= WER_MAX_NESTING_LEVEL)
- logChildren = false;
-
- // no need to log any children since the address is invalid anyway
- if (address == NULL || address == DWORD_PTR(-1))
- logChildren = false;
-
- pszCurrBuffer = DumpTypeIndex(pszCurrBuffer, modBase, innerTypeID, nestingLevel + 1,
- address, bHandled, Name, addressStr, false, logChildren);
-
- if (!bHandled)
- {
- BasicType basicType = GetBasicType(dwTypeIndex, modBase);
- if (symbolDetails.top().Type.empty())
- symbolDetails.top().Type = rgBaseType[basicType];
-
- if (address == NULL)
- symbolDetails.top().Value = "NULL";
- else if (address == DWORD_PTR(-1))
- symbolDetails.top().Value = "<Unable to read memory>";
- else
- {
- // Get the size of the child member
- ULONG64 length;
- SymGetTypeInfo(m_hProcess, modBase, innerTypeID, TI_GET_LENGTH, &length);
- char buffer2[50];
- FormatOutputValue(buffer2, basicType, length, (PVOID)address, sizeof(buffer));
- symbolDetails.top().Value = buffer2;
- }
- bHandled = true;
- return pszCurrBuffer;
- }
- else if (address == NULL)
- symbolDetails.top().Value = "NULL";
- else if (address == DWORD_PTR(-1))
- {
- symbolDetails.top().Value = "<Unable to read memory>";
- bHandled = true;
- return pszCurrBuffer;
- }
- }
- break;
- case SymTagData:
- if (SymGetTypeInfo(m_hProcess, modBase, dwTypeIndex, TI_GET_TYPEID, &innerTypeID))
- {
- DWORD innerTypeTag;
- if (!SymGetTypeInfo(m_hProcess, modBase, innerTypeID, TI_GET_SYMTAG, &innerTypeTag))
- break;
-
- switch (innerTypeTag)
- {
- case SymTagUDT:
- if (nestingLevel >= WER_MAX_NESTING_LEVEL)
- logChildren = false;
- pszCurrBuffer = DumpTypeIndex(pszCurrBuffer, modBase, innerTypeID, nestingLevel + 1,
- offset, bHandled, symbolDetails.top().Name.c_str(), "", false, logChildren);
- break;
- case SymTagPointerType:
- if (Name != NULL && Name[0] != '\0')
- symbolDetails.top().Name = Name;
- pszCurrBuffer = DumpTypeIndex(pszCurrBuffer, modBase, innerTypeID, nestingLevel + 1,
- offset, bHandled, symbolDetails.top().Name.c_str(), "", false, logChildren);
- break;
- case SymTagArrayType:
- pszCurrBuffer = DumpTypeIndex(pszCurrBuffer, modBase, innerTypeID, nestingLevel + 1,
- offset, bHandled, symbolDetails.top().Name.c_str(), "", false, logChildren);
- break;
- default:
- break;
- }
- }
- break;
- case SymTagArrayType:
- if (SymGetTypeInfo(m_hProcess, modBase, dwTypeIndex, TI_GET_TYPEID, &innerTypeID))
- {
- symbolDetails.top().HasChildren = true;
-
- BasicType basicType = btNoType;
- pszCurrBuffer = DumpTypeIndex(pszCurrBuffer, modBase, innerTypeID, nestingLevel + 1,
- offset, bHandled, Name, "", false, false);
-
- // Set Value back to an empty string since the Array object itself has no value, only its elements have
- symbolDetails.top().Value.clear();
-
- DWORD elementsCount;
- if (SymGetTypeInfo(m_hProcess, modBase, dwTypeIndex, TI_GET_COUNT, &elementsCount))
- symbolDetails.top().Suffix += "[" + std::to_string(elementsCount) + "]";
- else
- symbolDetails.top().Suffix += "[<unknown count>]";
-
- if (!bHandled)
- {
- basicType = GetBasicType(dwTypeIndex, modBase);
- if (symbolDetails.top().Type.empty())
- symbolDetails.top().Type = rgBaseType[basicType];
- bHandled = true;
- }
-
- // Get the size of the child member
- ULONG64 length;
- SymGetTypeInfo(m_hProcess, modBase, innerTypeID, TI_GET_LENGTH, &length);
-
- char buffer[50];
- switch (basicType)
- {
- case btChar:
- case btStdString:
- FormatOutputValue(buffer, basicType, length, (PVOID)offset, sizeof(buffer), elementsCount);
- symbolDetails.top().Value = buffer;
- break;
- default:
- for (DWORD index = 0; index < elementsCount && index < WER_MAX_ARRAY_ELEMENTS_COUNT; index++)
- {
- pszCurrBuffer = PushSymbolDetail(pszCurrBuffer);
- symbolDetails.top().Suffix += "[" + std::to_string(index) + "]";
- FormatOutputValue(buffer, basicType, length, (PVOID)(offset + length * index), sizeof(buffer));
- symbolDetails.top().Value = buffer;
- pszCurrBuffer = PopSymbolDetail(pszCurrBuffer);
- }
- break;
- }
-
- return pszCurrBuffer;
- }
- break;
- case SymTagBaseType:
- break;
- case SymTagEnum:
- return pszCurrBuffer;
- default:
- break;
- }
-
- // Determine how many children this type has.
- DWORD dwChildrenCount = 0;
- SymGetTypeInfo(m_hProcess, modBase, dwTypeIndex, TI_GET_CHILDRENCOUNT, &dwChildrenCount);
-
- if (!dwChildrenCount) // If no children, we're done
- return pszCurrBuffer;
-
- // Prepare to get an array of "TypeIds", representing each of the children.
- // SymGetTypeInfo(TI_FINDCHILDREN) expects more memory than just a
- // TI_FINDCHILDREN_PARAMS struct has. Use derivation to accomplish this.
- struct FINDCHILDREN : TI_FINDCHILDREN_PARAMS
- {
- ULONG MoreChildIds[1024*2];
- FINDCHILDREN(){Count = sizeof(MoreChildIds) / sizeof(MoreChildIds[0]);}
- } children;
-
- children.Count = dwChildrenCount;
- children.Start= 0;
-
- // Get the array of TypeIds, one for each child type
- if (!SymGetTypeInfo(m_hProcess, modBase, dwTypeIndex, TI_FINDCHILDREN,
- &children))
- {
- return pszCurrBuffer;
- }
-
- // Iterate through each of the children
- for (unsigned i = 0; i < dwChildrenCount; i++)
- {
- DWORD symTag;
- SymGetTypeInfo(m_hProcess, modBase, children.ChildId[i], TI_GET_SYMTAG, &symTag);
-
- if (symTag == SymTagFunction ||
- symTag == SymTagEnum ||
- symTag == SymTagTypedef ||
- symTag == SymTagVTable)
- continue;
-
- // Ignore static fields
- DWORD dataKind;
- SymGetTypeInfo(m_hProcess, modBase, children.ChildId[i], TI_GET_DATAKIND, &dataKind);
- if (dataKind == DataIsStaticLocal ||
- dataKind == DataIsGlobal ||
- dataKind == DataIsStaticMember)
- continue;
-
-
- symbolDetails.top().HasChildren = true;
- if (!logChildren)
- {
- bHandled = false;
- return pszCurrBuffer;
- }
-
- // Recurse for each of the child types
- bool bHandled2;
- BasicType basicType = GetBasicType(children.ChildId[i], modBase);
-
- // Get the offset of the child member, relative to its parent
- DWORD dwMemberOffset;
- SymGetTypeInfo(m_hProcess, modBase, children.ChildId[i],
- TI_GET_OFFSET, &dwMemberOffset);
-
- // Calculate the address of the member
- DWORD_PTR dwFinalOffset = offset + dwMemberOffset;
-
- pszCurrBuffer = DumpTypeIndex(pszCurrBuffer, modBase,
- children.ChildId[i], nestingLevel+1,
- dwFinalOffset, bHandled2, ""/*Name */, "", true, true);
-
- // If the child wasn't a UDT, format it appropriately
- if (!bHandled2)
- {
- if (symbolDetails.top().Type.empty())
- symbolDetails.top().Type = rgBaseType[basicType];
-
- // Get the real "TypeId" of the child. We need this for the
- // SymGetTypeInfo(TI_GET_TYPEID) call below.
- DWORD typeId;
- SymGetTypeInfo(m_hProcess, modBase, children.ChildId[i],
- TI_GET_TYPEID, &typeId);
-
- // Get the size of the child member
- ULONG64 length;
- SymGetTypeInfo(m_hProcess, modBase, typeId, TI_GET_LENGTH, &length);
-
- char buffer[50];
- FormatOutputValue(buffer, basicType, length, (PVOID)dwFinalOffset, sizeof(buffer));
- symbolDetails.top().Value = buffer;
- }
-
- pszCurrBuffer = PopSymbolDetail(pszCurrBuffer);
- }
-
- bHandled = true;
- return pszCurrBuffer;
-}
-
-void WheatyExceptionReport::FormatOutputValue(char * pszCurrBuffer,
-BasicType basicType,
-DWORD64 length,
-PVOID pAddress,
-size_t bufferSize,
-size_t countOverride)
-{
- __try
- {
- switch (basicType)
- {
- case btChar:
- {
- // Special case handling for char[] type
- if (countOverride != 0)
- length = countOverride;
- else
- length = strlen((char*)pAddress);
- if (length > bufferSize - 6)
- pszCurrBuffer += sprintf(pszCurrBuffer, "\"%.*s...\"", (DWORD)(bufferSize - 6), (char*)pAddress);
- else
- pszCurrBuffer += sprintf(pszCurrBuffer, "\"%.*s\"", (DWORD)length, (char*)pAddress);
- break;
- }
- case btStdString:
- {
- std::string* value = static_cast<std::string*>(pAddress);
- if (value->length() > bufferSize - 6)
- pszCurrBuffer += sprintf(pszCurrBuffer, "\"%.*s...\"", (DWORD)(bufferSize - 6), value->c_str());
- else
- pszCurrBuffer += sprintf(pszCurrBuffer, "\"%s\"", value->c_str());
- break;
- }
- default:
- // Format appropriately (assuming it's a 1, 2, or 4 bytes (!!!)
- if (length == 1)
- pszCurrBuffer += sprintf(pszCurrBuffer, "0x%X", *(PBYTE)pAddress);
- else if (length == 2)
- pszCurrBuffer += sprintf(pszCurrBuffer, "0x%X", *(PWORD)pAddress);
- else if (length == 4)
- {
- if (basicType == btFloat)
- pszCurrBuffer += sprintf(pszCurrBuffer, "%f", *(PFLOAT)pAddress);
- else
- pszCurrBuffer += sprintf(pszCurrBuffer, "0x%X", *(PDWORD)pAddress);
- }
- else if (length == 8)
- {
- if (basicType == btFloat)
- {
- pszCurrBuffer += sprintf(pszCurrBuffer, "%f",
- *(double *)pAddress);
- }
- else
- pszCurrBuffer += sprintf(pszCurrBuffer, "0x%I64X",
- *(DWORD64*)pAddress);
- }
- else
- {
- #if _WIN64
- pszCurrBuffer += sprintf(pszCurrBuffer, "0x%I64X", (DWORD64)pAddress);
- #else
- pszCurrBuffer += sprintf(pszCurrBuffer, "0x%X", (DWORD)pAddress);
- #endif
- }
- break;
- }
- }
- __except (EXCEPTION_EXECUTE_HANDLER)
- {
-#if _WIN64
- pszCurrBuffer += sprintf(pszCurrBuffer, "0x%I64X <Unable to read memory>", (DWORD64)pAddress);
-#else
- pszCurrBuffer += sprintf(pszCurrBuffer, "0x%X <Unable to read memory>", (DWORD)pAddress);
-#endif
- }
-}
-
-BasicType
-WheatyExceptionReport::GetBasicType(DWORD typeIndex, DWORD64 modBase)
-{
- BasicType basicType;
- if (SymGetTypeInfo(m_hProcess, modBase, typeIndex,
- TI_GET_BASETYPE, &basicType))
- {
- return basicType;
- }
-
- // Get the real "TypeId" of the child. We need this for the
- // SymGetTypeInfo(TI_GET_TYPEID) call below.
- DWORD typeId;
- if (SymGetTypeInfo(m_hProcess, modBase, typeIndex, TI_GET_TYPEID, &typeId))
- {
- if (SymGetTypeInfo(m_hProcess, modBase, typeId, TI_GET_BASETYPE,
- &basicType))
- {
- return basicType;
- }
- }
-
- return btNoType;
-}
-
-DWORD_PTR WheatyExceptionReport::DereferenceUnsafePointer(DWORD_PTR address)
-{
- __try
- {
- return *(PDWORD_PTR)address;
- }
- __except (EXCEPTION_EXECUTE_HANDLER)
- {
- return DWORD_PTR(-1);
- }
-}
-
-//============================================================================
-// Helper function that writes to the report file, and allows the user to use
-// printf style formating
-//============================================================================
-int __cdecl WheatyExceptionReport::_tprintf(const TCHAR * format, ...)
-{
- int retValue;
- va_list argptr;
- va_start(argptr, format);
- if (stackOverflowException)
- {
- retValue = heapprintf(format, argptr);
- va_end(argptr);
- }
- else
- {
- retValue = stackprintf(format, argptr);
- va_end(argptr);
- }
-
- return retValue;
-}
-
-int __cdecl WheatyExceptionReport::stackprintf(const TCHAR * format, va_list argptr)
-{
- int retValue;
- DWORD cbWritten;
-
- TCHAR szBuff[WER_LARGE_BUFFER_SIZE];
- retValue = vsprintf(szBuff, format, argptr);
- WriteFile(m_hReportFile, szBuff, retValue * sizeof(TCHAR), &cbWritten, 0);
-
- return retValue;
-}
-
-int __cdecl WheatyExceptionReport::heapprintf(const TCHAR * format, va_list argptr)
-{
- int retValue;
- DWORD cbWritten;
- TCHAR* szBuff = (TCHAR*)malloc(sizeof(TCHAR) * WER_LARGE_BUFFER_SIZE);
- retValue = vsprintf(szBuff, format, argptr);
- WriteFile(m_hReportFile, szBuff, retValue * sizeof(TCHAR), &cbWritten, 0);
- free(szBuff);
-
- return retValue;
-}
-
-bool WheatyExceptionReport::StoreSymbol(DWORD type, DWORD_PTR offset)
-{
- return symbols.insert(SymbolPair(type, offset)).second;
-}
-
-void WheatyExceptionReport::ClearSymbols()
-{
- symbols.clear();
- while (!symbolDetails.empty())
- symbolDetails.pop();
-}
-
-char* WheatyExceptionReport::PushSymbolDetail(char* pszCurrBuffer)
-{
- // Log current symbol and then add another to the stack to keep the hierarchy format
- pszCurrBuffer = PrintSymbolDetail(pszCurrBuffer);
- symbolDetails.emplace();
- return pszCurrBuffer;
-}
-
-char* WheatyExceptionReport::PopSymbolDetail(char* pszCurrBuffer)
-{
- pszCurrBuffer = PrintSymbolDetail(pszCurrBuffer);
- symbolDetails.pop();
- return pszCurrBuffer;
-}
-
-char* WheatyExceptionReport::PrintSymbolDetail(char* pszCurrBuffer)
-{
- if (symbolDetails.empty())
- return pszCurrBuffer;
-
- // Don't log anything if has been logged already or if it's empty
- if (symbolDetails.top().Logged || symbolDetails.top().empty())
- return pszCurrBuffer;
-
- // Add appropriate indentation level (since this routine is recursive)
- for (size_t i = 0; i < symbolDetails.size(); i++)
- pszCurrBuffer += sprintf(pszCurrBuffer, "\t");
-
- pszCurrBuffer += sprintf(pszCurrBuffer, "%s\r\n", symbolDetails.top().ToString().c_str());
-
- return pszCurrBuffer;
-}
-
-#endif // _WIN32
diff --git a/src/server/shared/Debugging/WheatyExceptionReport.h b/src/server/shared/Debugging/WheatyExceptionReport.h
deleted file mode 100644
index 8c2479d5232..00000000000
--- a/src/server/shared/Debugging/WheatyExceptionReport.h
+++ /dev/null
@@ -1,210 +0,0 @@
-#ifndef _WHEATYEXCEPTIONREPORT_
-#define _WHEATYEXCEPTIONREPORT_
-
-#if PLATFORM == PLATFORM_WINDOWS && !defined(__MINGW32__)
-
-#include <dbghelp.h>
-#include <set>
-#include <stdlib.h>
-#include <stack>
-#include <mutex>
-#define countof _countof
-
-#define WER_MAX_ARRAY_ELEMENTS_COUNT 10
-#define WER_MAX_NESTING_LEVEL 5
-#define WER_LARGE_BUFFER_SIZE 1024 * 128
-
-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,
-
- // Custom types
- btStdString = 101
-};
-
-enum DataKind // Stolen from CVCONST.H in the DIA 2.0 SDK
-{
- DataIsUnknown,
- DataIsLocal,
- DataIsStaticLocal,
- DataIsParam,
- DataIsObjectPtr,
- DataIsFileStatic,
- DataIsGlobal,
- DataIsMember,
- DataIsStaticMember,
- DataIsConstant
-};
-
-const char* const rgBaseType[] =
-{
- "<user defined>", // btNoType = 0,
- "void", // btVoid = 1,
- "char",//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",
- "uint8",
- "uint16",
- "uint32",
- "uint64",
- "uint128",
- "<currency>", // btCurrency = 25,
- "<date>", // btDate = 26,
- "VARIANT", // btVariant = 27,
- "<complex>", // btComplex = 28,
- "<bit>", // btBit = 29,
- "BSTR", // btBSTR = 30,
- "HRESULT" // btHresult = 31
-};
-
-struct SymbolPair
-{
- SymbolPair(DWORD type, DWORD_PTR offset)
- {
- _type = type;
- _offset = offset;
- }
-
- bool operator<(const SymbolPair& other) const
- {
- return _offset < other._offset ||
- (_offset == other._offset && _type < other._type);
- }
-
- DWORD _type;
- DWORD_PTR _offset;
-};
-typedef std::set<SymbolPair> SymbolPairs;
-
-struct SymbolDetail
-{
- SymbolDetail() : Prefix(), Type(), Suffix(), Name(), Value(), Logged(false), HasChildren(false) {}
-
- std::string ToString()
- {
- Logged = true;
- std::string formatted = Prefix + Type + Suffix;
- if (!Name.empty())
- {
- if (!formatted.empty())
- formatted += " ";
- formatted += Name;
- }
- if (!Value.empty())
- formatted += " = " + Value;
- return formatted;
- }
-
- bool empty() const
- {
- return Value.empty() && !HasChildren;
- }
-
- std::string Prefix;
- std::string Type;
- std::string Suffix;
- std::string Name;
- std::string Value;
- bool Logged;
- bool HasChildren;
-};
-
-class WheatyExceptionReport
-{
- public:
-
- WheatyExceptionReport();
- ~WheatyExceptionReport();
-
- // entry point where control comes on an unhandled exception
- static LONG WINAPI WheatyUnhandledExceptionFilter(
- PEXCEPTION_POINTERS pExceptionInfo);
-
- static void printTracesForAllThreads(bool);
- 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, STACKFRAME64 *, char * pszBuffer, unsigned cbBuffer);
-
- static char * DumpTypeIndex(char *, DWORD64, DWORD, unsigned, DWORD_PTR, bool &, const char*, char*, bool, bool);
-
- static void FormatOutputValue(char * pszCurrBuffer, BasicType basicType, DWORD64 length, PVOID pAddress, size_t bufferSize, size_t countOverride = 0);
-
- static BasicType GetBasicType(DWORD typeIndex, DWORD64 modBase);
- static DWORD_PTR DereferenceUnsafePointer(DWORD_PTR address);
-
- static int __cdecl _tprintf(const TCHAR * format, ...);
- static int __cdecl stackprintf(const TCHAR * format, va_list argptr);
- static int __cdecl heapprintf(const TCHAR * format, va_list argptr);
-
- static bool StoreSymbol(DWORD type , DWORD_PTR offset);
- static void ClearSymbols();
-
- // Variables used by the class
- static TCHAR m_szLogFileName[MAX_PATH];
- static TCHAR m_szDumpFileName[MAX_PATH];
- static LPTOP_LEVEL_EXCEPTION_FILTER m_previousFilter;
- static HANDLE m_hReportFile;
- static HANDLE m_hDumpFile;
- static HANDLE m_hProcess;
- static SymbolPairs symbols;
- static std::stack<SymbolDetail> symbolDetails;
- static bool stackOverflowException;
- static bool alreadyCrashed;
- static std::mutex alreadyCrashedLock;
-
- static char* PushSymbolDetail(char* pszCurrBuffer);
- static char* PopSymbolDetail(char* pszCurrBuffer);
- static char* PrintSymbolDetail(char* pszCurrBuffer);
-
-};
-
-extern WheatyExceptionReport g_WheatyExceptionReport; // global instance of class
-#endif // _WIN32
-#endif // _WHEATYEXCEPTIONREPORT_
-
diff --git a/src/server/shared/Define.h b/src/server/shared/Define.h
deleted file mode 100644
index 97e07cef8b3..00000000000
--- a/src/server/shared/Define.h
+++ /dev/null
@@ -1,107 +0,0 @@
-/*
- * Copyright (C) 2008-2015 TrinityCore <http://www.trinitycore.org/>
- * 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, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef TRINITY_DEFINE_H
-#define TRINITY_DEFINE_H
-
-#include "CompilerDefs.h"
-
-#if COMPILER == COMPILER_GNU
-# if !defined(__STDC_FORMAT_MACROS)
-# define __STDC_FORMAT_MACROS
-# endif
-# if !defined(__STDC_CONSTANT_MACROS)
-# define __STDC_CONSTANT_MACROS
-# endif
-# if !defined(_GLIBCXX_USE_NANOSLEEP)
-# define _GLIBCXX_USE_NANOSLEEP
-# endif
-# if defined(HELGRIND)
-# include <valgrind/helgrind.h>
-# define _GLIBCXX_SYNCHRONIZATION_HAPPENS_BEFORE(A) ANNOTATE_HAPPENS_BEFORE(A)
-# define _GLIBCXX_SYNCHRONIZATION_HAPPENS_AFTER(A) ANNOTATE_HAPPENS_AFTER(A)
-# endif
-#endif
-
-#include <cstddef>
-#include <cinttypes>
-#include <climits>
-
-#define TRINITY_LITTLEENDIAN 0
-#define TRINITY_BIGENDIAN 1
-
-#if !defined(TRINITY_ENDIAN)
-# if defined (BOOST_BIG_ENDIAN)
-# define TRINITY_ENDIAN TRINITY_BIGENDIAN
-# else
-# define TRINITY_ENDIAN TRINITY_LITTLEENDIAN
-# endif
-#endif
-
-#if PLATFORM == PLATFORM_WINDOWS
-# define TRINITY_PATH_MAX MAX_PATH
-# define _USE_MATH_DEFINES
-# ifndef DECLSPEC_NORETURN
-# define DECLSPEC_NORETURN __declspec(noreturn)
-# endif //DECLSPEC_NORETURN
-# ifndef DECLSPEC_DEPRECATED
-# define DECLSPEC_DEPRECATED __declspec(deprecated)
-# endif //DECLSPEC_DEPRECATED
-#else //PLATFORM != PLATFORM_WINDOWS
-# define TRINITY_PATH_MAX PATH_MAX
-# define DECLSPEC_NORETURN
-# define DECLSPEC_DEPRECATED
-#endif //PLATFORM
-
-#if !defined(COREDEBUG)
-# define TRINITY_INLINE inline
-#else //COREDEBUG
-# if !defined(TRINITY_DEBUG)
-# define TRINITY_DEBUG
-# endif //TRINITY_DEBUG
-# define TRINITY_INLINE
-#endif //!COREDEBUG
-
-#if COMPILER == COMPILER_GNU
-# define ATTR_NORETURN __attribute__((__noreturn__))
-# define ATTR_PRINTF(F, V) __attribute__ ((__format__ (__printf__, F, V)))
-# define ATTR_DEPRECATED __attribute__((__deprecated__))
-#else //COMPILER != COMPILER_GNU
-# define ATTR_NORETURN
-# define ATTR_PRINTF(F, V)
-# define ATTR_DEPRECATED
-#endif //COMPILER == COMPILER_GNU
-
-#define UI64FMTD "%" PRIu64
-#define UI64LIT(N) UINT64_C(N)
-
-#define SI64FMTD "%" PRId64
-#define SI64LIT(N) INT64_C(N)
-
-#define SZFMTD "%" PRIuPTR
-
-typedef int64_t int64;
-typedef int32_t int32;
-typedef int16_t int16;
-typedef int8_t int8;
-typedef uint64_t uint64;
-typedef uint32_t uint32;
-typedef uint16_t uint16;
-typedef uint8_t uint8;
-
-#endif //TRINITY_DEFINE_H
diff --git a/src/server/shared/Logging/Appender.cpp b/src/server/shared/Logging/Appender.cpp
deleted file mode 100644
index d19ef8cf96f..00000000000
--- a/src/server/shared/Logging/Appender.cpp
+++ /dev/null
@@ -1,109 +0,0 @@
-/*
- * Copyright (C) 2008-2015 TrinityCore <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, see <http://www.gnu.org/licenses/>.
- */
-
-#include "Appender.h"
-#include "Common.h"
-#include "Util.h"
-#include "StringFormat.h"
-
-#include <utility>
-#include <sstream>
-
-std::string LogMessage::getTimeStr(time_t time)
-{
- tm aTm;
- localtime_r(&time, &aTm);
- 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);
-}
-
-std::string LogMessage::getTimeStr()
-{
- return getTimeStr(mtime);
-}
-
-Appender::Appender(uint8 _id, std::string const& _name, LogLevel _level /* = LOG_LEVEL_DISABLED */, AppenderFlags _flags /* = APPENDER_FLAGS_NONE */):
-id(_id), name(_name), level(_level), flags(_flags) { }
-
-Appender::~Appender() { }
-
-uint8 Appender::getId() const
-{
- return id;
-}
-
-std::string const& Appender::getName() const
-{
- return name;
-}
-
-LogLevel Appender::getLogLevel() const
-{
- return level;
-}
-
-AppenderFlags Appender::getFlags() const
-{
- return flags;
-}
-
-void Appender::setLogLevel(LogLevel _level)
-{
- level = _level;
-}
-
-void Appender::write(LogMessage* message)
-{
- if (!level || level > message->level)
- return;
-
- std::ostringstream ss;
-
- if (flags & APPENDER_FLAGS_PREFIX_TIMESTAMP)
- ss << message->getTimeStr() << ' ';
-
- if (flags & APPENDER_FLAGS_PREFIX_LOGLEVEL)
- ss << Trinity::StringFormat("%-5s ", Appender::getLogLevelString(message->level));
-
- if (flags & APPENDER_FLAGS_PREFIX_LOGFILTERTYPE)
- ss << '[' << message->type << "] ";
-
- message->prefix = ss.str();
- _write(message);
-}
-
-const char* Appender::getLogLevelString(LogLevel level)
-{
- switch (level)
- {
- case LOG_LEVEL_FATAL:
- return "FATAL";
- case LOG_LEVEL_ERROR:
- return "ERROR";
- case LOG_LEVEL_WARN:
- return "WARN";
- case LOG_LEVEL_INFO:
- return "INFO";
- case LOG_LEVEL_DEBUG:
- return "DEBUG";
- case LOG_LEVEL_TRACE:
- return "TRACE";
- default:
- return "DISABLED";
- }
-}
diff --git a/src/server/shared/Logging/Appender.h b/src/server/shared/Logging/Appender.h
deleted file mode 100644
index 7c5aa41924d..00000000000
--- a/src/server/shared/Logging/Appender.h
+++ /dev/null
@@ -1,134 +0,0 @@
-/*
- * Copyright (C) 2008-2015 TrinityCore <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, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef APPENDER_H
-#define APPENDER_H
-
-#include <unordered_map>
-#include <stdexcept>
-#include <string>
-#include <time.h>
-#include <type_traits>
-#include <vector>
-#include <utility>
-#include "Define.h"
-
-// Values assigned have their equivalent in enum ACE_Log_Priority
-enum LogLevel
-{
- LOG_LEVEL_DISABLED = 0,
- LOG_LEVEL_TRACE = 1,
- LOG_LEVEL_DEBUG = 2,
- LOG_LEVEL_INFO = 3,
- LOG_LEVEL_WARN = 4,
- LOG_LEVEL_ERROR = 5,
- LOG_LEVEL_FATAL = 6
-};
-
-const uint8 MaxLogLevels = 6;
-
-enum AppenderType
-{
- APPENDER_NONE,
- APPENDER_CONSOLE,
- APPENDER_FILE,
- APPENDER_DB
-};
-
-enum AppenderFlags
-{
- APPENDER_FLAGS_NONE = 0x00,
- APPENDER_FLAGS_PREFIX_TIMESTAMP = 0x01,
- APPENDER_FLAGS_PREFIX_LOGLEVEL = 0x02,
- APPENDER_FLAGS_PREFIX_LOGFILTERTYPE = 0x04,
- APPENDER_FLAGS_USE_TIMESTAMP = 0x08, // only used by FileAppender
- APPENDER_FLAGS_MAKE_FILE_BACKUP = 0x10 // only used by FileAppender
-};
-
-struct LogMessage
-{
- LogMessage(LogLevel _level, std::string const& _type, std::string&& _text)
- : level(_level), type(_type), text(std::forward<std::string>(_text)), mtime(time(NULL))
- { }
-
- LogMessage(LogMessage const& /*other*/) = delete;
- LogMessage& operator=(LogMessage const& /*other*/) = delete;
-
- static std::string getTimeStr(time_t time);
- std::string getTimeStr();
-
- LogLevel const level;
- std::string const type;
- std::string const text;
- std::string prefix;
- std::string param1;
- time_t mtime;
-
- ///@ Returns size of the log message content in bytes
- uint32 Size() const
- {
- return static_cast<uint32>(prefix.size() + text.size());
- }
-};
-
-class Appender
-{
- public:
- Appender(uint8 _id, std::string const& name, LogLevel level = LOG_LEVEL_DISABLED, AppenderFlags flags = APPENDER_FLAGS_NONE);
- virtual ~Appender();
-
- uint8 getId() const;
- std::string const& getName() const;
- virtual AppenderType getType() const = 0;
- LogLevel getLogLevel() const;
- AppenderFlags getFlags() const;
-
- void setLogLevel(LogLevel);
- void write(LogMessage* message);
- static const char* getLogLevelString(LogLevel level);
- virtual void setRealmId(uint32 /*realmId*/) { }
-
- private:
- virtual void _write(LogMessage const* /*message*/) = 0;
-
- uint8 id;
- std::string name;
- LogLevel level;
- AppenderFlags flags;
-};
-
-typedef std::unordered_map<uint8, Appender*> AppenderMap;
-
-typedef std::vector<char const*> ExtraAppenderArgs;
-typedef Appender*(*AppenderCreatorFn)(uint8 id, std::string const& name, LogLevel level, AppenderFlags flags, ExtraAppenderArgs extraArgs);
-typedef std::unordered_map<uint8, AppenderCreatorFn> AppenderCreatorMap;
-
-template<class AppenderImpl>
-Appender* CreateAppender(uint8 id, std::string const& name, LogLevel level, AppenderFlags flags, ExtraAppenderArgs extraArgs)
-{
- return new AppenderImpl(id, name, level, flags, std::forward<ExtraAppenderArgs>(extraArgs));
-}
-
-class InvalidAppenderArgsException : public std::length_error
-{
-public:
- using std::length_error::length_error;
-
- explicit InvalidAppenderArgsException(std::string const& message) : length_error(message) { }
-};
-
-#endif
diff --git a/src/server/shared/Logging/AppenderConsole.cpp b/src/server/shared/Logging/AppenderConsole.cpp
deleted file mode 100644
index 531df266aa1..00000000000
--- a/src/server/shared/Logging/AppenderConsole.cpp
+++ /dev/null
@@ -1,200 +0,0 @@
-/*
- * Copyright (C) 2008-2015 TrinityCore <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, see <http://www.gnu.org/licenses/>.
- */
-
-#include <sstream>
-
-#include "AppenderConsole.h"
-#include "Config.h"
-#include "Util.h"
-
-#if PLATFORM == PLATFORM_WINDOWS
- #include <Windows.h>
-#endif
-
-AppenderConsole::AppenderConsole(uint8 id, std::string const& name, LogLevel level, AppenderFlags flags, ExtraAppenderArgs extraArgs)
- : Appender(id, name, level, flags), _colored(false)
-{
- for (uint8 i = 0; i < MaxLogLevels; ++i)
- _colors[i] = ColorTypes(MaxColors);
-
- if (!extraArgs.empty())
- InitColors(extraArgs[0]);
-}
-
-void AppenderConsole::InitColors(std::string const& str)
-{
- if (str.empty())
- {
- _colored = false;
- return;
- }
-
- int color[MaxLogLevels];
-
- std::istringstream ss(str);
-
- for (uint8 i = 0; i < MaxLogLevels; ++i)
- {
- ss >> color[i];
-
- if (!ss)
- return;
-
- if (color[i] < 0 || color[i] >= MaxColors)
- return;
- }
-
- for (uint8 i = 0; i < MaxLogLevels; ++i)
- _colors[i] = ColorTypes(color[i]);
-
- _colored = true;
-}
-
-void AppenderConsole::SetColor(bool stdout_stream, ColorTypes color)
-{
-#if PLATFORM == PLATFORM_WINDOWS
- static WORD WinColorFG[MaxColors] =
- {
- 0, // BLACK
- FOREGROUND_RED, // RED
- FOREGROUND_GREEN, // GREEN
- FOREGROUND_RED | FOREGROUND_GREEN, // BROWN
- FOREGROUND_BLUE, // BLUE
- FOREGROUND_RED | FOREGROUND_BLUE, // MAGENTA
- FOREGROUND_GREEN | FOREGROUND_BLUE, // CYAN
- FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE, // WHITE
- // YELLOW
- FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_INTENSITY,
- // RED_BOLD
- FOREGROUND_RED | FOREGROUND_INTENSITY,
- // GREEN_BOLD
- FOREGROUND_GREEN | FOREGROUND_INTENSITY,
- FOREGROUND_BLUE | FOREGROUND_INTENSITY, // BLUE_BOLD
- // MAGENTA_BOLD
- FOREGROUND_RED | FOREGROUND_BLUE | FOREGROUND_INTENSITY,
- // CYAN_BOLD
- FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_INTENSITY,
- // WHITE_BOLD
- FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_INTENSITY
- };
-
- HANDLE hConsole = GetStdHandle(stdout_stream ? STD_OUTPUT_HANDLE : STD_ERROR_HANDLE);
- SetConsoleTextAttribute(hConsole, WinColorFG[color]);
-#else
- enum ANSITextAttr
- {
- TA_NORMAL = 0,
- TA_BOLD = 1,
- TA_BLINK = 5,
- TA_REVERSE = 7
- };
-
- enum ANSIFgTextAttr
- {
- FG_BLACK = 30,
- FG_RED,
- FG_GREEN,
- FG_BROWN,
- FG_BLUE,
- FG_MAGENTA,
- FG_CYAN,
- FG_WHITE,
- FG_YELLOW
- };
-
- enum ANSIBgTextAttr
- {
- BG_BLACK = 40,
- BG_RED,
- BG_GREEN,
- BG_BROWN,
- BG_BLUE,
- BG_MAGENTA,
- BG_CYAN,
- BG_WHITE
- };
-
- static uint8 UnixColorFG[MaxColors] =
- {
- FG_BLACK, // BLACK
- FG_RED, // RED
- FG_GREEN, // GREEN
- FG_BROWN, // BROWN
- FG_BLUE, // BLUE
- FG_MAGENTA, // MAGENTA
- FG_CYAN, // CYAN
- FG_WHITE, // WHITE
- FG_YELLOW, // YELLOW
- FG_RED, // LRED
- FG_GREEN, // LGREEN
- FG_BLUE, // LBLUE
- FG_MAGENTA, // LMAGENTA
- FG_CYAN, // LCYAN
- FG_WHITE // LWHITE
- };
-
- fprintf((stdout_stream? stdout : stderr), "\x1b[%d%sm", UnixColorFG[color], (color >= YELLOW && color < MaxColors ? ";1" : ""));
- #endif
-}
-
-void AppenderConsole::ResetColor(bool stdout_stream)
-{
- #if PLATFORM == PLATFORM_WINDOWS
- HANDLE hConsole = GetStdHandle(stdout_stream ? STD_OUTPUT_HANDLE : STD_ERROR_HANDLE);
- SetConsoleTextAttribute(hConsole, FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED);
- #else
- fprintf((stdout_stream ? stdout : stderr), "\x1b[0m");
- #endif
-}
-
-void AppenderConsole::_write(LogMessage const* message)
-{
- bool stdout_stream = !(message->level == LOG_LEVEL_ERROR || message->level == LOG_LEVEL_FATAL);
-
- if (_colored)
- {
- uint8 index;
- switch (message->level)
- {
- case LOG_LEVEL_TRACE:
- index = 5;
- break;
- case LOG_LEVEL_DEBUG:
- index = 4;
- break;
- case LOG_LEVEL_INFO:
- index = 3;
- break;
- case LOG_LEVEL_WARN:
- index = 2;
- break;
- case LOG_LEVEL_FATAL:
- index = 0;
- break;
- case LOG_LEVEL_ERROR: // No break on purpose
- default:
- index = 1;
- break;
- }
-
- SetColor(stdout_stream, _colors[index]);
- utf8printf(stdout_stream ? stdout : stderr, "%s%s\n", message->prefix.c_str(), message->text.c_str());
- ResetColor(stdout_stream);
- }
- else
- utf8printf(stdout_stream ? stdout : stderr, "%s%s\n", message->prefix.c_str(), message->text.c_str());
-}
diff --git a/src/server/shared/Logging/AppenderConsole.h b/src/server/shared/Logging/AppenderConsole.h
deleted file mode 100644
index 6b30505c6bd..00000000000
--- a/src/server/shared/Logging/AppenderConsole.h
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * Copyright (C) 2008-2015 TrinityCore <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, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef APPENDERCONSOLE_H
-#define APPENDERCONSOLE_H
-
-#include <string>
-#include "Appender.h"
-
-enum ColorTypes
-{
- BLACK,
- RED,
- GREEN,
- BROWN,
- BLUE,
- MAGENTA,
- CYAN,
- GREY,
- YELLOW,
- LRED,
- LGREEN,
- LBLUE,
- LMAGENTA,
- LCYAN,
- WHITE
-};
-
-const uint8 MaxColors = uint8(WHITE) + 1;
-
-class AppenderConsole : public Appender
-{
- public:
- typedef std::integral_constant<AppenderType, APPENDER_CONSOLE>::type TypeIndex;
-
- AppenderConsole(uint8 _id, std::string const& name, LogLevel level, AppenderFlags flags, ExtraAppenderArgs extraArgs);
- void InitColors(const std::string& init_str);
- AppenderType getType() const override { return TypeIndex::value; }
-
- private:
- void SetColor(bool stdout_stream, ColorTypes color);
- void ResetColor(bool stdout_stream);
- void _write(LogMessage const* message) override;
- bool _colored;
- ColorTypes _colors[MaxLogLevels];
-};
-
-#endif
diff --git a/src/server/shared/Logging/AppenderFile.cpp b/src/server/shared/Logging/AppenderFile.cpp
deleted file mode 100644
index d33818626fe..00000000000
--- a/src/server/shared/Logging/AppenderFile.cpp
+++ /dev/null
@@ -1,124 +0,0 @@
-/*
- * Copyright (C) 2008-2015 TrinityCore <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, see <http://www.gnu.org/licenses/>.
- */
-
-#include "AppenderFile.h"
-#include "Common.h"
-#include "StringFormat.h"
-#include "Log.h"
-
-#if PLATFORM == PLATFORM_WINDOWS
-# include <Windows.h>
-#endif
-
-AppenderFile::AppenderFile(uint8 id, std::string const& name, LogLevel level, AppenderFlags flags, ExtraAppenderArgs extraArgs) :
- Appender(id, name, level, flags),
- logfile(NULL),
- _logDir(sLog->GetLogsDir()),
- _fileSize(0)
-{
- if (extraArgs.empty())
- throw InvalidAppenderArgsException(Trinity::StringFormat("Log::CreateAppenderFromConfig: Missing file name for appender %s\n", name.c_str()));
-
- _fileName = extraArgs[0];
-
- char const* mode = "a";
- if (extraArgs.size() > 1)
- mode = extraArgs[1];
-
- if (flags & APPENDER_FLAGS_USE_TIMESTAMP)
- {
- size_t dot_pos = _fileName.find_last_of(".");
- if (dot_pos != std::string::npos)
- _fileName.insert(dot_pos, sLog->GetLogsTimestamp());
- else
- _fileName += sLog->GetLogsTimestamp();
- }
-
- if (extraArgs.size() > 2)
- _maxFileSize = atoi(extraArgs[2]);
-
- _dynamicName = std::string::npos != _fileName.find("%s");
- _backup = (flags & APPENDER_FLAGS_MAKE_FILE_BACKUP) != 0;
-
- if (!_dynamicName)
- logfile = OpenFile(_fileName, mode, !strcmp(mode, "w") && _backup);
-}
-
-AppenderFile::~AppenderFile()
-{
- CloseFile();
-}
-
-void AppenderFile::_write(LogMessage const* message)
-{
- bool exceedMaxSize = _maxFileSize > 0 && (_fileSize.load() + message->Size()) > _maxFileSize;
-
- if (_dynamicName)
- {
- char namebuf[TRINITY_PATH_MAX];
- snprintf(namebuf, TRINITY_PATH_MAX, _fileName.c_str(), message->param1.c_str());
- // always use "a" with dynamic name otherwise it could delete the log we wrote in last _write() call
- FILE* file = OpenFile(namebuf, "a", _backup || exceedMaxSize);
- if (!file)
- return;
- fprintf(file, "%s%s\n", message->prefix.c_str(), message->text.c_str());
- fflush(file);
- _fileSize += uint64(message->Size());
- fclose(file);
- return;
- }
- else if (exceedMaxSize)
- logfile = OpenFile(_fileName, "w", true);
-
- if (!logfile)
- return;
-
- fprintf(logfile, "%s%s\n", message->prefix.c_str(), message->text.c_str());
- fflush(logfile);
- _fileSize += uint64(message->Size());
-}
-
-FILE* AppenderFile::OpenFile(std::string const& filename, std::string const& mode, bool backup)
-{
- std::string fullName(_logDir + filename);
- if (backup)
- {
- CloseFile();
- std::string newName(fullName);
- newName.push_back('.');
- newName.append(LogMessage::getTimeStr(time(NULL)));
- std::replace(newName.begin(), newName.end(), ':', '-');
- rename(fullName.c_str(), newName.c_str()); // no error handling... if we couldn't make a backup, just ignore
- }
-
- if (FILE* ret = fopen(fullName.c_str(), mode.c_str()))
- {
- _fileSize = ftell(ret);
- return ret;
- }
-
- return NULL;
-}
-
-void AppenderFile::CloseFile()
-{
- if (logfile)
- {
- fclose(logfile);
- logfile = NULL;
- }
-}
diff --git a/src/server/shared/Logging/AppenderFile.h b/src/server/shared/Logging/AppenderFile.h
deleted file mode 100644
index c2781eb1ee9..00000000000
--- a/src/server/shared/Logging/AppenderFile.h
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Copyright (C) 2008-2015 TrinityCore <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, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef APPENDERFILE_H
-#define APPENDERFILE_H
-
-#include <atomic>
-#include "Appender.h"
-
-class AppenderFile : public Appender
-{
- public:
- typedef std::integral_constant<AppenderType, APPENDER_FILE>::type TypeIndex;
-
- AppenderFile(uint8 id, std::string const& name, LogLevel level, AppenderFlags flags, ExtraAppenderArgs extraArgs);
- ~AppenderFile();
- FILE* OpenFile(std::string const& name, std::string const& mode, bool backup);
- AppenderType getType() const override { return TypeIndex::value; }
-
- private:
- void CloseFile();
- void _write(LogMessage const* message) override;
- FILE* logfile;
- std::string _fileName;
- std::string _logDir;
- bool _dynamicName;
- bool _backup;
- uint64 _maxFileSize;
- std::atomic<uint64> _fileSize;
-};
-
-#endif
diff --git a/src/server/shared/Logging/Log.cpp b/src/server/shared/Logging/Log.cpp
deleted file mode 100644
index 5075815ad54..00000000000
--- a/src/server/shared/Logging/Log.cpp
+++ /dev/null
@@ -1,348 +0,0 @@
-/*
- * Copyright (C) 2008-2015 TrinityCore <http://www.trinitycore.org/>
- * Copyright (C) 2005-2008 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, see <http://www.gnu.org/licenses/>.
- */
-
-#include "Log.h"
-#include "Common.h"
-#include "Config.h"
-#include "Util.h"
-#include "AppenderConsole.h"
-#include "AppenderFile.h"
-#include "AppenderDB.h"
-#include "LogOperation.h"
-
-#include <cstdio>
-#include <sstream>
-
-Log::Log() : _ioService(nullptr), _strand(nullptr)
-{
- m_logsTimestamp = "_" + GetTimestampStr();
- RegisterAppender<AppenderConsole>();
- RegisterAppender<AppenderFile>();
-}
-
-Log::~Log()
-{
- delete _strand;
- Close();
-}
-
-uint8 Log::NextAppenderId()
-{
- return AppenderId++;
-}
-
-int32 GetConfigIntDefault(std::string base, const char* name, int32 value)
-{
- base.append(name);
- return sConfigMgr->GetIntDefault(base.c_str(), value);
-}
-
-std::string GetConfigStringDefault(std::string base, const char* name, const char* value)
-{
- base.append(name);
- return sConfigMgr->GetStringDefault(base.c_str(), value);
-}
-
-Appender* Log::GetAppenderByName(std::string const& name)
-{
- AppenderMap::iterator it = appenders.begin();
- while (it != appenders.end() && it->second && it->second->getName() != name)
- ++it;
-
- return it == appenders.end() ? NULL : it->second;
-}
-
-void Log::CreateAppenderFromConfig(std::string const& appenderName)
-{
- if (appenderName.empty())
- return;
-
- // Format=type, level, flags, optional1, optional2
- // if type = File. optional1 = file and option2 = mode
- // if type = Console. optional1 = Color
- std::string options = sConfigMgr->GetStringDefault(appenderName.c_str(), "");
-
- Tokenizer tokens(options, ',');
- Tokenizer::const_iterator iter = tokens.begin();
-
- size_t size = tokens.size();
- std::string name = appenderName.substr(9);
-
- if (size < 2)
- {
- fprintf(stderr, "Log::CreateAppenderFromConfig: Wrong configuration for appender %s. Config line: %s\n", name.c_str(), options.c_str());
- return;
- }
-
- AppenderFlags flags = APPENDER_FLAGS_NONE;
- AppenderType type = AppenderType(atoi(*iter++));
- LogLevel level = LogLevel(atoi(*iter++));
-
- if (level > LOG_LEVEL_FATAL)
- {
- fprintf(stderr, "Log::CreateAppenderFromConfig: Wrong Log Level %d for appender %s\n", level, name.c_str());
- return;
- }
-
- if (size > 2)
- flags = AppenderFlags(atoi(*iter++));
-
- auto factoryFunction = appenderFactory.find(type);
- if (factoryFunction == appenderFactory.end())
- {
- fprintf(stderr, "Log::CreateAppenderFromConfig: Unknown type %d for appender %s\n", type, name.c_str());
- return;
- }
-
- try
- {
- Appender* appender = factoryFunction->second(NextAppenderId(), name, level, flags, ExtraAppenderArgs(iter, tokens.end()));
- appenders[appender->getId()] = appender;
- }
- catch (InvalidAppenderArgsException const& iaae)
- {
- fprintf(stderr, "%s", iaae.what());
- }
-}
-
-void Log::CreateLoggerFromConfig(std::string const& appenderName)
-{
- if (appenderName.empty())
- return;
-
- LogLevel level = LOG_LEVEL_DISABLED;
- uint8 type = uint8(-1);
-
- std::string options = sConfigMgr->GetStringDefault(appenderName.c_str(), "");
- std::string name = appenderName.substr(7);
-
- if (options.empty())
- {
- fprintf(stderr, "Log::CreateLoggerFromConfig: Missing config option Logger.%s\n", name.c_str());
- return;
- }
-
- Tokenizer tokens(options, ',');
- Tokenizer::const_iterator iter = tokens.begin();
-
- if (tokens.size() != 2)
- {
- fprintf(stderr, "Log::CreateLoggerFromConfig: Wrong config option Logger.%s=%s\n", name.c_str(), options.c_str());
- return;
- }
-
- Logger& logger = loggers[name];
- if (!logger.getName().empty())
- {
- fprintf(stderr, "Error while configuring Logger %s. Already defined\n", name.c_str());
- return;
- }
-
- level = LogLevel(atoi(*iter++));
- if (level > LOG_LEVEL_FATAL)
- {
- fprintf(stderr, "Log::CreateLoggerFromConfig: Wrong Log Level %u for logger %s\n", type, name.c_str());
- return;
- }
-
- if (level < lowestLogLevel)
- lowestLogLevel = level;
-
- logger.Create(name, level);
- //fprintf(stdout, "Log::CreateLoggerFromConfig: Created Logger %s, Level %u\n", name.c_str(), level);
-
- std::istringstream ss(*iter);
- std::string str;
-
- ss >> str;
- while (ss)
- {
- if (Appender* appender = GetAppenderByName(str))
- {
- logger.addAppender(appender->getId(), appender);
- //fprintf(stdout, "Log::CreateLoggerFromConfig: Added Appender %s to Logger %s\n", appender->getName().c_str(), name.c_str());
- }
- else
- fprintf(stderr, "Error while configuring Appender %s in Logger %s. Appender does not exist", str.c_str(), name.c_str());
- ss >> str;
- }
-}
-
-void Log::ReadAppendersFromConfig()
-{
- std::list<std::string> keys = sConfigMgr->GetKeysByString("Appender.");
-
- while (!keys.empty())
- {
- CreateAppenderFromConfig(keys.front());
- keys.pop_front();
- }
-}
-
-void Log::ReadLoggersFromConfig()
-{
- std::list<std::string> keys = sConfigMgr->GetKeysByString("Logger.");
-
- while (!keys.empty())
- {
- CreateLoggerFromConfig(keys.front());
- keys.pop_front();
- }
-
- // Bad config configuration, creating default config
- if (loggers.find(LOGGER_ROOT) == loggers.end())
- {
- fprintf(stderr, "Wrong Loggers configuration. Review your Logger config section.\n"
- "Creating default loggers [root (Error), server (Info)] to console\n");
-
- Close(); // Clean any Logger or Appender created
-
- AppenderConsole* appender = new AppenderConsole(NextAppenderId(), "Console", LOG_LEVEL_DEBUG, APPENDER_FLAGS_NONE, ExtraAppenderArgs());
- appenders[appender->getId()] = appender;
-
- Logger& logger = loggers[LOGGER_ROOT];
- logger.Create(LOGGER_ROOT, LOG_LEVEL_ERROR);
- logger.addAppender(appender->getId(), appender);
-
- logger = loggers["server"];
- logger.Create("server", LOG_LEVEL_ERROR);
- logger.addAppender(appender->getId(), appender);
- }
-}
-
-void Log::write(std::unique_ptr<LogMessage>&& msg) const
-{
- Logger const* logger = GetLoggerByType(msg->type);
-
- if (_ioService)
- {
- auto logOperation = std::shared_ptr<LogOperation>(new LogOperation(logger, std::move(msg)));
-
- _ioService->post(_strand->wrap([logOperation](){ logOperation->call(); }));
- }
- else
- logger->write(msg.get());
-}
-
-std::string Log::GetTimestampStr()
-{
- time_t tt = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now());
-
- std::tm aTm;
- localtime_r(&tt, &aTm);
-
- // 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)
- return Trinity::StringFormat("%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);
-}
-
-bool Log::SetLogLevel(std::string const& name, const char* newLevelc, bool isLogger /* = true */)
-{
- LogLevel newLevel = LogLevel(atoi(newLevelc));
- if (newLevel < 0)
- return false;
-
- if (isLogger)
- {
- LoggerMap::iterator it = loggers.begin();
- while (it != loggers.end() && it->second.getName() != name)
- ++it;
-
- if (it == loggers.end())
- return false;
-
- it->second.setLogLevel(newLevel);
-
- if (newLevel != LOG_LEVEL_DISABLED && newLevel < lowestLogLevel)
- lowestLogLevel = newLevel;
- }
- else
- {
- Appender* appender = GetAppenderByName(name);
- if (!appender)
- return false;
-
- appender->setLogLevel(newLevel);
- }
-
- return true;
-}
-
-void Log::outCharDump(char const* str, uint32 accountId, uint64 guid, char const* name)
-{
- if (!str || !ShouldLog("entities.player.dump", LOG_LEVEL_INFO))
- return;
-
- std::ostringstream ss;
- ss << "== START DUMP == (account: " << accountId << " guid: " << guid << " name: " << name
- << ")\n" << str << "\n== END DUMP ==\n";
-
- std::unique_ptr<LogMessage> msg(new LogMessage(LOG_LEVEL_INFO, "entities.player.dump", ss.str()));
- std::ostringstream param;
- param << guid << '_' << name;
-
- msg->param1 = param.str();
-
- write(std::move(msg));
-}
-
-void Log::SetRealmId(uint32 id)
-{
- for (AppenderMap::iterator it = appenders.begin(); it != appenders.end(); ++it)
- it->second->setRealmId(id);
-}
-
-void Log::Close()
-{
- loggers.clear();
- for (AppenderMap::iterator it = appenders.begin(); it != appenders.end(); ++it)
- delete it->second;
-
- appenders.clear();
-}
-
-void Log::Initialize(boost::asio::io_service* ioService)
-{
- if (ioService)
- {
- _ioService = ioService;
- _strand = new boost::asio::strand(*ioService);
- }
-
- LoadFromConfig();
-}
-
-void Log::LoadFromConfig()
-{
- Close();
-
- lowestLogLevel = LOG_LEVEL_FATAL;
- AppenderId = 0;
- m_logsDir = sConfigMgr->GetStringDefault("LogsDir", "");
- if (!m_logsDir.empty())
- if ((m_logsDir.at(m_logsDir.length() - 1) != '/') && (m_logsDir.at(m_logsDir.length() - 1) != '\\'))
- m_logsDir.push_back('/');
-
- ReadAppendersFromConfig();
- ReadLoggersFromConfig();
-}
diff --git a/src/server/shared/Logging/Log.h b/src/server/shared/Logging/Log.h
deleted file mode 100644
index a15bb4ad485..00000000000
--- a/src/server/shared/Logging/Log.h
+++ /dev/null
@@ -1,216 +0,0 @@
-/*
- * Copyright (C) 2008-2015 TrinityCore <http://www.trinitycore.org/>
- * 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, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef TRINITYCORE_LOG_H
-#define TRINITYCORE_LOG_H
-
-#include "Define.h"
-#include "Appender.h"
-#include "Logger.h"
-#include "StringFormat.h"
-#include "Common.h"
-#include <boost/asio/io_service.hpp>
-#include <boost/asio/strand.hpp>
-
-#include <stdarg.h>
-#include <unordered_map>
-#include <string>
-#include <memory>
-
-#define LOGGER_ROOT "root"
-
-class Log
-{
- typedef std::unordered_map<std::string, Logger> LoggerMap;
-
- private:
- Log();
- ~Log();
-
- public:
-
- static Log* instance()
- {
- static Log instance;
- return &instance;
- }
-
- void Initialize(boost::asio::io_service* ioService);
- void LoadFromConfig();
- void Close();
- bool ShouldLog(std::string const& type, LogLevel level) const;
- bool SetLogLevel(std::string const& name, char const* level, bool isLogger = true);
-
- template<typename Format, typename... Args>
- inline void outMessage(std::string const& filter, LogLevel const level, Format&& fmt, Args&&... args)
- {
- write(Trinity::make_unique<LogMessage>(level, filter,
- Trinity::StringFormat(std::forward<Format>(fmt), std::forward<Args>(args)...)));
- }
-
- template<typename Format, typename... Args>
- void outCommand(uint32 account, Format&& fmt, Args&&... args)
- {
- if (!ShouldLog("commands.gm", LOG_LEVEL_INFO))
- return;
-
- std::unique_ptr<LogMessage> msg =
- Trinity::make_unique<LogMessage>(LOG_LEVEL_INFO, "commands.gm",
- Trinity::StringFormat(std::forward<Format>(fmt), std::forward<Args>(args)...));
-
- msg->param1 = std::to_string(account);
-
- write(std::move(msg));
- }
-
- void outCharDump(char const* str, uint32 account_id, uint64 guid, char const* name);
-
- void SetRealmId(uint32 id);
-
- template<class AppenderImpl>
- void RegisterAppender()
- {
- using Index = typename AppenderImpl::TypeIndex;
- auto itr = appenderFactory.find(Index::value);
- ASSERT(itr == appenderFactory.end());
- appenderFactory[Index::value] = &CreateAppender<AppenderImpl>;
- }
-
- std::string const& GetLogsDir() const { return m_logsDir; }
- std::string const& GetLogsTimestamp() const { return m_logsTimestamp; }
-
- private:
- static std::string GetTimestampStr();
- void write(std::unique_ptr<LogMessage>&& msg) const;
-
- Logger const* GetLoggerByType(std::string const& type) const;
- Appender* GetAppenderByName(std::string const& name);
- uint8 NextAppenderId();
- void CreateAppenderFromConfig(std::string const& name);
- void CreateLoggerFromConfig(std::string const& name);
- void ReadAppendersFromConfig();
- void ReadLoggersFromConfig();
-
- AppenderCreatorMap appenderFactory;
- AppenderMap appenders;
- LoggerMap loggers;
- uint8 AppenderId;
- LogLevel lowestLogLevel;
-
- std::string m_logsDir;
- std::string m_logsTimestamp;
-
- boost::asio::io_service* _ioService;
- boost::asio::strand* _strand;
-};
-
-inline Logger const* Log::GetLoggerByType(std::string const& type) const
-{
- LoggerMap::const_iterator it = loggers.find(type);
- if (it != loggers.end())
- return &(it->second);
-
- if (type == LOGGER_ROOT)
- return NULL;
-
- std::string parentLogger = LOGGER_ROOT;
- size_t found = type.find_last_of(".");
- if (found != std::string::npos)
- parentLogger = type.substr(0,found);
-
- return GetLoggerByType(parentLogger);
-}
-
-inline bool Log::ShouldLog(std::string const& type, LogLevel level) const
-{
- // TODO: Use cache to store "Type.sub1.sub2": "Type" equivalence, should
- // Speed up in cases where requesting "Type.sub1.sub2" but only configured
- // Logger "Type"
-
- // Don't even look for a logger if the LogLevel is lower than lowest log levels across all loggers
- if (level < lowestLogLevel)
- return false;
-
- Logger const* logger = GetLoggerByType(type);
- if (!logger)
- return false;
-
- LogLevel logLevel = logger->getLogLevel();
- return logLevel != LOG_LEVEL_DISABLED && logLevel <= level;
-}
-
-#define sLog Log::instance()
-
-#define LOG_EXCEPTION_FREE(filterType__, level__, ...) \
- { \
- try \
- { \
- sLog->outMessage(filterType__, level__, __VA_ARGS__); \
- } \
- catch (std::exception& e) \
- { \
- sLog->outMessage("server", LOG_LEVEL_ERROR, "Wrong format occurred (%s) at %s:%u.", \
- e.what(), __FILE__, __LINE__); \
- } \
- }
-
-#if PLATFORM != PLATFORM_WINDOWS
-void check_args(const char*, ...) ATTR_PRINTF(1, 2);
-void check_args(std::string const&, ...);
-
-// This will catch format errors on build time
-#define TC_LOG_MESSAGE_BODY(filterType__, level__, ...) \
- do { \
- if (sLog->ShouldLog(filterType__, level__)) \
- { \
- if (false) \
- check_args(__VA_ARGS__); \
- \
- LOG_EXCEPTION_FREE(filterType__, level__, __VA_ARGS__); \
- } \
- } while (0)
-#else
-#define TC_LOG_MESSAGE_BODY(filterType__, level__, ...) \
- __pragma(warning(push)) \
- __pragma(warning(disable:4127)) \
- do { \
- if (sLog->ShouldLog(filterType__, level__)) \
- LOG_EXCEPTION_FREE(filterType__, level__, __VA_ARGS__); \
- } while (0) \
- __pragma(warning(pop))
-#endif
-
-#define TC_LOG_TRACE(filterType__, ...) \
- TC_LOG_MESSAGE_BODY(filterType__, LOG_LEVEL_TRACE, __VA_ARGS__)
-
-#define TC_LOG_DEBUG(filterType__, ...) \
- TC_LOG_MESSAGE_BODY(filterType__, LOG_LEVEL_DEBUG, __VA_ARGS__)
-
-#define TC_LOG_INFO(filterType__, ...) \
- TC_LOG_MESSAGE_BODY(filterType__, LOG_LEVEL_INFO, __VA_ARGS__)
-
-#define TC_LOG_WARN(filterType__, ...) \
- TC_LOG_MESSAGE_BODY(filterType__, LOG_LEVEL_WARN, __VA_ARGS__)
-
-#define TC_LOG_ERROR(filterType__, ...) \
- TC_LOG_MESSAGE_BODY(filterType__, LOG_LEVEL_ERROR, __VA_ARGS__)
-
-#define TC_LOG_FATAL(filterType__, ...) \
- TC_LOG_MESSAGE_BODY(filterType__, LOG_LEVEL_FATAL, __VA_ARGS__)
-
-#endif
diff --git a/src/server/shared/Logging/LogOperation.cpp b/src/server/shared/Logging/LogOperation.cpp
deleted file mode 100644
index bcd923c705e..00000000000
--- a/src/server/shared/Logging/LogOperation.cpp
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * Copyright (C) 2008-2015 TrinityCore <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, see <http://www.gnu.org/licenses/>.
- */
-
-#include "LogOperation.h"
-#include "Logger.h"
-
-int LogOperation::call()
-{
- logger->write(msg.get());
- return 0;
-}
diff --git a/src/server/shared/Logging/LogOperation.h b/src/server/shared/Logging/LogOperation.h
deleted file mode 100644
index ffdd35c3c09..00000000000
--- a/src/server/shared/Logging/LogOperation.h
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Copyright (C) 2008-2015 TrinityCore <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, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef LOGOPERATION_H
-#define LOGOPERATION_H
-
-#include <memory>
-
-class Logger;
-struct LogMessage;
-
-class LogOperation
-{
- public:
- LogOperation(Logger const* _logger, std::unique_ptr<LogMessage>&& _msg)
- : logger(_logger), msg(std::forward<std::unique_ptr<LogMessage>>(_msg))
- { }
-
- ~LogOperation() { }
-
- int call();
-
- protected:
- Logger const* logger;
- std::unique_ptr<LogMessage> msg;
-};
-
-#endif
diff --git a/src/server/shared/Logging/Logger.cpp b/src/server/shared/Logging/Logger.cpp
deleted file mode 100644
index 3b02eb47575..00000000000
--- a/src/server/shared/Logging/Logger.cpp
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * Copyright (C) 2008-2015 TrinityCore <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, see <http://www.gnu.org/licenses/>.
- */
-
-#include "Logger.h"
-
-Logger::Logger(): name(""), level(LOG_LEVEL_DISABLED) { }
-
-void Logger::Create(std::string const& _name, LogLevel _level)
-{
- name = _name;
- level = _level;
-}
-
-std::string const& Logger::getName() const
-{
- return name;
-}
-
-LogLevel Logger::getLogLevel() const
-{
- return level;
-}
-
-void Logger::addAppender(uint8 id, Appender* appender)
-{
- appenders[id] = appender;
-}
-
-void Logger::delAppender(uint8 id)
-{
- appenders.erase(id);
-}
-
-void Logger::setLogLevel(LogLevel _level)
-{
- level = _level;
-}
-
-void Logger::write(LogMessage* message) const
-{
- if (!level || level > message->level || message->text.empty())
- {
- //fprintf(stderr, "Logger::write: Logger %s, Level %u. Msg %s Level %u WRONG LEVEL MASK OR EMPTY MSG\n", getName().c_str(), getLogLevel(), message.text.c_str(), message.level);
- return;
- }
-
- for (AppenderMap::const_iterator it = appenders.begin(); it != appenders.end(); ++it)
- if (it->second)
- it->second->write(message);
-}
diff --git a/src/server/shared/Logging/Logger.h b/src/server/shared/Logging/Logger.h
deleted file mode 100644
index 1aee75c5d72..00000000000
--- a/src/server/shared/Logging/Logger.h
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Copyright (C) 2008-2015 TrinityCore <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, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef LOGGER_H
-#define LOGGER_H
-
-#include "Appender.h"
-
-class Logger
-{
- public:
- Logger();
-
- void Create(std::string const& name, LogLevel level);
- void addAppender(uint8 type, Appender *);
- void delAppender(uint8 type);
-
- std::string const& getName() const;
- LogLevel getLogLevel() const;
- void setLogLevel(LogLevel level);
- void write(LogMessage* message) const;
-
- private:
- std::string name;
- LogLevel level;
- AppenderMap appenders;
-};
-
-#endif
diff --git a/src/server/shared/PrecompiledHeaders/sharedPCH.h b/src/server/shared/PrecompiledHeaders/sharedPCH.h
index f4c18f89ec1..c09b24e6fd9 100644
--- a/src/server/shared/PrecompiledHeaders/sharedPCH.h
+++ b/src/server/shared/PrecompiledHeaders/sharedPCH.h
@@ -1,11 +1,4 @@
//add here most rarely modified headers to speed up debug build compilation
-#include "Common.h"
-#include "Log.h"
-#include "DatabaseWorker.h"
-#include "SQLOperation.h"
-#include "Errors.h"
#include "TypeList.h"
-#include "TaskScheduler.h"
-#include "EventMap.h"
#include "Revision.h"
diff --git a/src/server/shared/Utilities/ServiceWin32.cpp b/src/server/shared/Service/ServiceWin32.cpp
index 3e5e416b1a3..3e5e416b1a3 100644
--- a/src/server/shared/Utilities/ServiceWin32.cpp
+++ b/src/server/shared/Service/ServiceWin32.cpp
diff --git a/src/server/shared/Utilities/ServiceWin32.h b/src/server/shared/Service/ServiceWin32.h
index 9d9c732cd20..9d9c732cd20 100644
--- a/src/server/shared/Utilities/ServiceWin32.h
+++ b/src/server/shared/Service/ServiceWin32.h
diff --git a/src/server/shared/Threading/Callback.h b/src/server/shared/Threading/Callback.h
deleted file mode 100644
index 1f4ffc97cfc..00000000000
--- a/src/server/shared/Threading/Callback.h
+++ /dev/null
@@ -1,209 +0,0 @@
-/*
- * Copyright (C) 2008-2015 TrinityCore <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, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef _CALLBACK_H
-#define _CALLBACK_H
-
-#include <future>
-#include "QueryResult.h"
-
-typedef std::future<QueryResult> QueryResultFuture;
-typedef std::promise<QueryResult> QueryResultPromise;
-typedef std::future<PreparedQueryResult> PreparedQueryResultFuture;
-typedef std::promise<PreparedQueryResult> PreparedQueryResultPromise;
-
-#define CALLBACK_STAGE_INVALID uint8(-1)
-
-template <typename Result, typename ParamType, bool chain = false>
-class QueryCallback
-{
- public:
- QueryCallback() : _param(), _stage(chain ? 0 : CALLBACK_STAGE_INVALID) { }
-
- //! The parameter of this function should be a resultset returned from either .AsyncQuery or .AsyncPQuery
- void SetFutureResult(std::future<Result> value)
- {
- _result = std::move(value);
- }
-
- std::future<Result>& GetFutureResult()
- {
- return _result;
- }
-
- int IsReady()
- {
- return _result.valid() && _result.wait_for(std::chrono::seconds(0)) == std::future_status::ready;
- }
-
- void GetResult(Result& res)
- {
- res = _result.get();
- }
-
- void FreeResult()
- {
- // Nothing to do here, the constructor of std::future will take care of the cleanup
- }
-
- void SetParam(ParamType value)
- {
- _param = value;
- }
-
- ParamType GetParam()
- {
- return _param;
- }
-
- //! Resets the stage of the callback chain
- void ResetStage()
- {
- if (!chain)
- return;
-
- _stage = 0;
- }
-
- //! Advances the callback chain to the next stage, so upper level code can act on its results accordingly
- void NextStage()
- {
- if (!chain)
- return;
-
- ++_stage;
- }
-
- //! Returns the callback stage (or CALLBACK_STAGE_INVALID if invalid)
- uint8 GetStage()
- {
- return _stage;
- }
-
- //! Resets all underlying variables (param, result and stage)
- void Reset()
- {
- SetParam(ParamType());
- FreeResult();
- ResetStage();
- }
-
- private:
- std::future<Result> _result;
- ParamType _param;
- uint8 _stage;
-
- QueryCallback(QueryCallback const& right) = delete;
- QueryCallback& operator=(QueryCallback const& right) = delete;
-};
-
-template <typename Result, typename ParamType1, typename ParamType2, bool chain = false>
-class QueryCallback_2
-{
- public:
- QueryCallback_2() : _stage(chain ? 0 : CALLBACK_STAGE_INVALID) { }
-
- //! The parameter of this function should be a resultset returned from either .AsyncQuery or .AsyncPQuery
- void SetFutureResult(std::future<Result> value)
- {
- _result = std::move(value);
- }
-
- std::future<Result>& GetFutureResult()
- {
- return _result;
- }
-
- int IsReady()
- {
- return _result.valid() && _result.wait_for(std::chrono::seconds(0)) == std::future_status::ready;
- }
-
- void GetResult(Result& res)
- {
- res = _result.get();
- }
-
- void FreeResult()
- {
- // Nothing to do here, the constructor of std::future will take care of the cleanup
- }
-
- void SetFirstParam(ParamType1 value)
- {
- _param_1 = value;
- }
-
- void SetSecondParam(ParamType2 value)
- {
- _param_2 = value;
- }
-
- ParamType1 GetFirstParam()
- {
- return _param_1;
- }
-
- ParamType2 GetSecondParam()
- {
- return _param_2;
- }
-
- //! Resets the stage of the callback chain
- void ResetStage()
- {
- if (!chain)
- return;
-
- _stage = 0;
- }
-
- //! Advances the callback chain to the next stage, so upper level code can act on its results accordingly
- void NextStage()
- {
- if (!chain)
- return;
-
- ++_stage;
- }
-
- //! Returns the callback stage (or CALLBACK_STAGE_INVALID if invalid)
- uint8 GetStage()
- {
- return _stage;
- }
-
- //! Resets all underlying variables (param, result and stage)
- void Reset()
- {
- SetFirstParam(NULL);
- SetSecondParam(NULL);
- FreeResult();
- ResetStage();
- }
-
- private:
- std::future<Result> _result;
- ParamType1 _param_1;
- ParamType2 _param_2;
- uint8 _stage;
-
- QueryCallback_2(QueryCallback_2 const& right) = delete;
- QueryCallback_2& operator=(QueryCallback_2 const& right) = delete;
-};
-
-#endif
diff --git a/src/server/shared/Threading/LockedQueue.h b/src/server/shared/Threading/LockedQueue.h
deleted file mode 100644
index 3abb0f4b8bc..00000000000
--- a/src/server/shared/Threading/LockedQueue.h
+++ /dev/null
@@ -1,144 +0,0 @@
-/*
- * Copyright (C) 2008-2015 TrinityCore <http://www.trinitycore.org/>
- * Copyright (C) 2005-2008 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, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef LOCKEDQUEUE_H
-#define LOCKEDQUEUE_H
-
-#include <deque>
-#include <mutex>
-
-template <class T, typename StorageType = std::deque<T> >
-class LockedQueue
-{
- //! Lock access to the queue.
- std::mutex _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();
-
- _queue.push_back(item);
-
- unlock();
- }
-
- //! Gets the next result in the queue, if any.
- bool next(T& result)
- {
- std::lock_guard<std::mutex> lock(_lock);
-
- if (_queue.empty())
- return false;
-
- result = _queue.front();
- _queue.pop_front();
-
- return true;
- }
-
- template<class Checker>
- bool next(T& result, Checker& check)
- {
- std::lock_guard<std::mutex> lock(_lock);
-
- if (_queue.empty())
- return false;
-
- result = _queue.front();
- if (!check.Process(result))
- return false;
-
- _queue.pop_front();
- return true;
- }
-
- //! Peeks at the top of the queue. Check if the queue is empty before calling! Remember to unlock after use if autoUnlock == false.
- T& peek(bool autoUnlock = false)
- {
- lock();
-
- T& result = _queue.front();
-
- if (autoUnlock)
- unlock();
-
- return result;
- }
-
- //! Cancels the queue.
- void cancel()
- {
- std::lock_guard<std::mutex> lock(_lock);
-
- _canceled = true;
- }
-
- //! Checks if the queue is cancelled.
- bool cancelled()
- {
- std::lock_guard<std::mutex> lock(_lock);
- return _canceled;
- }
-
- //! Locks the queue for access.
- void lock()
- {
- this->_lock.lock();
- }
-
- //! Unlocks the queue.
- void unlock()
- {
- this->_lock.unlock();
- }
-
- ///! Calls pop_front of the queue
- void pop_front()
- {
- std::lock_guard<std::mutex> lock(_lock);
- _queue.pop_front();
- }
-
- ///! Checks if we're empty or not with locks held
- bool empty()
- {
- std::lock_guard<std::mutex> lock(_lock);
- return _queue.empty();
- }
-};
-#endif
diff --git a/src/server/shared/Threading/ProcessPriority.h b/src/server/shared/Threading/ProcessPriority.h
deleted file mode 100644
index 2a8501a0249..00000000000
--- a/src/server/shared/Threading/ProcessPriority.h
+++ /dev/null
@@ -1,105 +0,0 @@
-/*
-* Copyright (C) 2008-2015 TrinityCore <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, see <http://www.gnu.org/licenses/>.
-*/
-
-#ifndef _PROCESSPRIO_H
-#define _PROCESSPRIO_H
-
-#include "Configuration/Config.h"
-
-#ifdef __linux__
-#include <sched.h>
-#include <sys/resource.h>
-#define PROCESS_HIGH_PRIORITY -15 // [-20, 19], default is 0
-#endif
-
-void SetProcessPriority(const std::string& logChannel)
-{
-// Suppresses Mac OS X Warning since logChannel isn't used.
-#if PLATFORM_APPLE
- (void)logChannel;
-#endif
-
-#if defined(_WIN32) || defined(__linux__)
-
- ///- Handle affinity for multiple processors and process priority
- uint32 affinity = sConfigMgr->GetIntDefault("UseProcessors", 0);
- bool highPriority = sConfigMgr->GetBoolDefault("ProcessPriority", false);
-
-#ifdef _WIN32 // Windows
-
- HANDLE hProcess = GetCurrentProcess();
- if (affinity > 0)
- {
- ULONG_PTR appAff;
- ULONG_PTR sysAff;
-
- if (GetProcessAffinityMask(hProcess, &appAff, &sysAff))
- {
- // remove non accessible processors
- ULONG_PTR currentAffinity = affinity & appAff;
-
- if (!currentAffinity)
- TC_LOG_ERROR(logChannel, "Processors marked in UseProcessors bitmask (hex) %x are not accessible. Accessible processors bitmask (hex): %x", affinity, appAff);
- else if (SetProcessAffinityMask(hProcess, currentAffinity))
- TC_LOG_INFO(logChannel, "Using processors (bitmask, hex): %x", currentAffinity);
- else
- TC_LOG_ERROR(logChannel, "Can't set used processors (hex): %x", currentAffinity);
- }
- }
-
- if (highPriority)
- {
- if (SetPriorityClass(hProcess, HIGH_PRIORITY_CLASS))
- TC_LOG_INFO(logChannel, "Process priority class set to HIGH");
- else
- TC_LOG_ERROR(logChannel, "Can't set process priority class.");
- }
-
-#else // Linux
-
- if (affinity > 0)
- {
- cpu_set_t mask;
- CPU_ZERO(&mask);
-
- for (unsigned int i = 0; i < sizeof(affinity) * 8; ++i)
- if (affinity & (1 << i))
- CPU_SET(i, &mask);
-
- if (sched_setaffinity(0, sizeof(mask), &mask))
- TC_LOG_ERROR(logChannel, "Can't set used processors (hex): %x, error: %s", affinity, strerror(errno));
- else
- {
- CPU_ZERO(&mask);
- sched_getaffinity(0, sizeof(mask), &mask);
- TC_LOG_INFO(logChannel, "Using processors (bitmask, hex): %lx", *(__cpu_mask*)(&mask));
- }
- }
-
- if (highPriority)
- {
- if (setpriority(PRIO_PROCESS, 0, PROCESS_HIGH_PRIORITY))
- TC_LOG_ERROR(logChannel, "Can't set process priority class, error: %s", strerror(errno));
- else
- TC_LOG_INFO(logChannel, "Process priority class set to %i", getpriority(PRIO_PROCESS, 0));
- }
-
-#endif
-#endif
-}
-
-#endif
diff --git a/src/server/shared/Threading/ProducerConsumerQueue.h b/src/server/shared/Threading/ProducerConsumerQueue.h
deleted file mode 100644
index 96546960393..00000000000
--- a/src/server/shared/Threading/ProducerConsumerQueue.h
+++ /dev/null
@@ -1,112 +0,0 @@
-/*
-* Copyright (C) 2008-2015 TrinityCore <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, see <http://www.gnu.org/licenses/>.
-*/
-
-#ifndef _PCQ_H
-#define _PCQ_H
-
-#include <condition_variable>
-#include <mutex>
-#include <queue>
-#include <atomic>
-#include <type_traits>
-
-template <typename T>
-class ProducerConsumerQueue
-{
-private:
- std::mutex _queueLock;
- std::queue<T> _queue;
- std::condition_variable _condition;
- std::atomic<bool> _shutdown;
-
-public:
-
- ProducerConsumerQueue<T>() : _shutdown(false) { }
-
- void Push(const T& value)
- {
- std::lock_guard<std::mutex> lock(_queueLock);
- _queue.push(std::move(value));
-
- _condition.notify_one();
- }
-
- bool Empty()
- {
- std::lock_guard<std::mutex> lock(_queueLock);
-
- return _queue.empty();
- }
-
- bool Pop(T& value)
- {
- std::lock_guard<std::mutex> lock(_queueLock);
-
- if (_queue.empty() || _shutdown)
- return false;
-
- value = _queue.front();
-
- _queue.pop();
-
- return true;
- }
-
- void WaitAndPop(T& value)
- {
- std::unique_lock<std::mutex> lock(_queueLock);
-
- // we could be using .wait(lock, predicate) overload here but it is broken
- // https://connect.microsoft.com/VisualStudio/feedback/details/1098841
- while (_queue.empty() && !_shutdown)
- _condition.wait(lock);
-
- if (_queue.empty() || _shutdown)
- return;
-
- value = _queue.front();
-
- _queue.pop();
- }
-
- void Cancel()
- {
- std::unique_lock<std::mutex> lock(_queueLock);
-
- while (!_queue.empty())
- {
- T& value = _queue.front();
-
- DeleteQueuedObject(value);
-
- _queue.pop();
- }
-
- _shutdown = true;
-
- _condition.notify_all();
- }
-
-private:
- template<typename E = T>
- typename std::enable_if<std::is_pointer<E>::value>::type DeleteQueuedObject(E& obj) { delete obj; }
-
- template<typename E = T>
- typename std::enable_if<!std::is_pointer<E>::value>::type DeleteQueuedObject(E const& /*packet*/) { }
-};
-
-#endif
diff --git a/src/server/shared/Utilities/ByteConverter.h b/src/server/shared/Utilities/ByteConverter.h
deleted file mode 100644
index a077de3eb0b..00000000000
--- a/src/server/shared/Utilities/ByteConverter.h
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * Copyright (C) 2008-2015 TrinityCore <http://www.trinitycore.org/>
- * 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, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef TRINITY_BYTECONVERTER_H
-#define TRINITY_BYTECONVERTER_H
-
-/** ByteConverter reverse your byte order. This is use
- for cross platform where they have different endians.
- */
-
-#include "Define.h"
-#include <algorithm>
-
-namespace ByteConverter
-{
- template<size_t T>
- inline void convert(char *val)
- {
- std::swap(*val, *(val + T - 1));
- convert<T - 2>(val + 1);
- }
-
- template<> inline void convert<0>(char *) { }
- template<> inline void convert<1>(char *) { } // ignore central byte
-
- template<typename T> inline void apply(T *val)
- {
- convert<sizeof(T)>((char *)(val));
- }
-}
-
-#if TRINITY_ENDIAN == TRINITY_BIGENDIAN
-template<typename T> inline void EndianConvert(T& val) { ByteConverter::apply<T>(&val); }
-template<typename T> inline void EndianConvertReverse(T&) { }
-template<typename T> inline void EndianConvertPtr(void* val) { ByteConverter::apply<T>(val); }
-template<typename T> inline void EndianConvertPtrReverse(void*) { }
-#else
-template<typename T> inline void EndianConvert(T&) { }
-template<typename T> inline void EndianConvertReverse(T& val) { ByteConverter::apply<T>(&val); }
-template<typename T> inline void EndianConvertPtr(void*) { }
-template<typename T> inline void EndianConvertPtrReverse(void* val) { ByteConverter::apply<T>(val); }
-#endif
-
-template<typename T> void EndianConvert(T*); // will generate link error
-template<typename T> void EndianConvertReverse(T*); // will generate link error
-
-inline void EndianConvert(uint8&) { }
-inline void EndianConvert( int8&) { }
-inline void EndianConvertReverse(uint8&) { }
-inline void EndianConvertReverse( int8&) { }
-
-#endif
-
diff --git a/src/server/shared/Utilities/Duration.h b/src/server/shared/Utilities/Duration.h
deleted file mode 100644
index 58a08e5842f..00000000000
--- a/src/server/shared/Utilities/Duration.h
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Copyright (C) 2008-2015 TrinityCore <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, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef _DURATION_H_
-#define _DURATION_H_
-
-#include <chrono>
-
-/// Milliseconds shorthand typedef.
-typedef std::chrono::milliseconds Milliseconds;
-
-/// Seconds shorthand typedef.
-typedef std::chrono::seconds Seconds;
-
-/// Minutes shorthand typedef.
-typedef std::chrono::minutes Minutes;
-
-/// Hours shorthand typedef.
-typedef std::chrono::hours Hours;
-
-/// Makes std::chrono_literals globally available.
-// ToDo: Enable this when TC supports C++14.
-// using namespace std::chrono_literals;
-
-#endif // _DURATION_H_
diff --git a/src/server/shared/Utilities/EventMap.cpp b/src/server/shared/Utilities/EventMap.cpp
deleted file mode 100644
index 8c3f60afe82..00000000000
--- a/src/server/shared/Utilities/EventMap.cpp
+++ /dev/null
@@ -1,136 +0,0 @@
-/*
- * Copyright (C) 2008-2015 TrinityCore <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, see <http://www.gnu.org/licenses/>.
- */
-
-#include "EventMap.h"
-
-void EventMap::Reset()
-{
- _eventMap.clear();
- _time = 0;
- _phase = 0;
-}
-
-void EventMap::SetPhase(uint8 phase)
-{
- if (!phase)
- _phase = 0;
- else if (phase <= 8)
- _phase = uint8(1 << (phase - 1));
-}
-
-void EventMap::ScheduleEvent(uint32 eventId, uint32 time, uint32 group /*= 0*/, uint8 phase /*= 0*/)
-{
- if (group && group <= 8)
- eventId |= (1 << (group + 15));
-
- if (phase && phase <= 8)
- eventId |= (1 << (phase + 23));
-
- _eventMap.insert(EventStore::value_type(_time + time, eventId));
-}
-
-uint32 EventMap::ExecuteEvent()
-{
- while (!Empty())
- {
- EventStore::iterator itr = _eventMap.begin();
-
- if (itr->first > _time)
- return 0;
- else if (_phase && (itr->second & 0xFF000000) && !((itr->second >> 24) & _phase))
- _eventMap.erase(itr);
- else
- {
- uint32 eventId = (itr->second & 0x0000FFFF);
- _lastEvent = itr->second; // include phase/group
- _eventMap.erase(itr);
- return eventId;
- }
- }
-
- return 0;
-}
-
-void EventMap::DelayEvents(uint32 delay, uint32 group)
-{
- if (!group || group > 8 || Empty())
- return;
-
- EventStore delayed;
-
- for (EventStore::iterator itr = _eventMap.begin(); itr != _eventMap.end();)
- {
- if (itr->second & (1 << (group + 15)))
- {
- delayed.insert(EventStore::value_type(itr->first + delay, itr->second));
- _eventMap.erase(itr++);
- }
- else
- ++itr;
- }
-
- _eventMap.insert(delayed.begin(), delayed.end());
-}
-
-void EventMap::CancelEvent(uint32 eventId)
-{
- if (Empty())
- return;
-
- for (EventStore::iterator itr = _eventMap.begin(); itr != _eventMap.end();)
- {
- if (eventId == (itr->second & 0x0000FFFF))
- _eventMap.erase(itr++);
- else
- ++itr;
- }
-}
-
-void EventMap::CancelEventGroup(uint32 group)
-{
- if (!group || group > 8 || Empty())
- return;
-
- for (EventStore::iterator itr = _eventMap.begin(); itr != _eventMap.end();)
- {
- if (itr->second & (1 << (group + 15)))
- _eventMap.erase(itr++);
- else
- ++itr;
- }
-}
-
-uint32 EventMap::GetNextEventTime(uint32 eventId) const
-{
- if (Empty())
- return 0;
-
- for (EventStore::const_iterator itr = _eventMap.begin(); itr != _eventMap.end(); ++itr)
- if (eventId == (itr->second & 0x0000FFFF))
- return itr->first;
-
- return 0;
-}
-
-uint32 EventMap::GetTimeUntilEvent(uint32 eventId) const
-{
- for (EventStore::const_iterator itr = _eventMap.begin(); itr != _eventMap.end(); ++itr)
- if (eventId == (itr->second & 0x0000FFFF))
- return itr->first - _time;
-
- return std::numeric_limits<uint32>::max();
-}
diff --git a/src/server/shared/Utilities/EventMap.h b/src/server/shared/Utilities/EventMap.h
deleted file mode 100644
index 021dffc4940..00000000000
--- a/src/server/shared/Utilities/EventMap.h
+++ /dev/null
@@ -1,342 +0,0 @@
-/*
- * Copyright (C) 2008-2015 TrinityCore <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, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef _EVENT_MAP_H_
-#define _EVENT_MAP_H_
-
-#include "Common.h"
-#include "Duration.h"
-#include "Util.h"
-
-class EventMap
-{
- /**
- * Internal storage type.
- * Key: Time as uint32 when the event should occur.
- * Value: The event data as uint32.
- *
- * Structure of event data:
- * - Bit 0 - 15: Event Id.
- * - Bit 16 - 23: Group
- * - Bit 24 - 31: Phase
- * - Pattern: 0xPPGGEEEE
- */
- typedef std::multimap<uint32, uint32> EventStore;
-
-public:
- EventMap() : _time(0), _phase(0), _lastEvent(0) { }
-
- /**
- * @name Reset
- * @brief Removes all scheduled events and resets time and phase.
- */
- void Reset();
-
- /**
- * @name Update
- * @brief Updates the timer of the event map.
- * @param time Value in ms to be added to time.
- */
- void Update(uint32 time)
- {
- _time += time;
- }
-
- /**
- * @name GetTimer
- * @return Current timer in ms value.
- */
- uint32 GetTimer() const
- {
- return _time;
- }
-
- /**
- * @name GetPhaseMask
- * @return Active phases as mask.
- */
- uint8 GetPhaseMask() const
- {
- return _phase;
- }
-
- /**
- * @name Empty
- * @return True, if there are no events scheduled.
- */
- bool Empty() const
- {
- return _eventMap.empty();
- }
-
- /**
- * @name SetPhase
- * @brief Sets the phase of the map (absolute).
- * @param phase Phase which should be set. Values: 1 - 8. 0 resets phase.
- */
- void SetPhase(uint8 phase);
-
- /**
- * @name AddPhase
- * @brief Activates the given phase (bitwise).
- * @param phase Phase which should be activated. Values: 1 - 8
- */
- void AddPhase(uint8 phase)
- {
- if (phase && phase <= 8)
- _phase |= uint8(1 << (phase - 1));
- }
-
- /**
- * @name RemovePhase
- * @brief Deactivates the given phase (bitwise).
- * @param phase Phase which should be deactivated. Values: 1 - 8.
- */
- void RemovePhase(uint8 phase)
- {
- if (phase && phase <= 8)
- _phase &= uint8(~(1 << (phase - 1)));
- }
-
- /**
- * @name ScheduleEvent
- * @brief Creates new event entry in map.
- * @param eventId The id of the new event.
- * @param time The time in milliseconds as std::chrono::duration until the event occurs.
- * @param group The group which the event is associated to. Has to be between 1 and 8. 0 means it has no group.
- * @param phase The phase in which the event can occur. Has to be between 1 and 8. 0 means it can occur in all phases.
- */
- void ScheduleEvent(uint32 eventId, Milliseconds const& time, uint32 group = 0, uint8 phase = 0)
- {
- ScheduleEvent(eventId, time.count(), group, phase);
- }
-
- /**
- * @name ScheduleEvent
- * @brief Creates new event entry in map.
- * @param eventId The id of the new event.
- * @param time The time in milliseconds until the event occurs.
- * @param group The group which the event is associated to. Has to be between 1 and 8. 0 means it has no group.
- * @param phase The phase in which the event can occur. Has to be between 1 and 8. 0 means it can occur in all phases.
- */
- void ScheduleEvent(uint32 eventId, uint32 time, uint32 group = 0, uint8 phase = 0);
-
- /**
- * @name RescheduleEvent
- * @brief Cancels the given event and reschedules it.
- * @param eventId The id of the event.
- * @param time The time in milliseconds as std::chrono::duration until the event occurs.
- * @param group The group which the event is associated to. Has to be between 1 and 8. 0 means it has no group.
- * @param phase The phase in which the event can occur. Has to be between 1 and 8. 0 means it can occur in all phases.
- */
- void RescheduleEvent(uint32 eventId, Milliseconds const& time, uint32 group = 0, uint8 phase = 0)
- {
- RescheduleEvent(eventId, time.count(), group, phase);
- }
-
- /**
- * @name RescheduleEvent
- * @brief Cancels the given event and reschedules it.
- * @param eventId The id of the event.
- * @param time The time in milliseconds until the event occurs.
- * @param group The group which the event is associated to. Has to be between 1 and 8. 0 means it has no group.
- * @param phase The phase in which the event can occur. Has to be between 1 and 8. 0 means it can occur in all phases.
- */
- void RescheduleEvent(uint32 eventId, uint32 time, uint32 group = 0, uint8 phase = 0)
- {
- CancelEvent(eventId);
- ScheduleEvent(eventId, time, group, phase);
- }
-
- /**
- * @name RepeatEvent
- * @brief Repeats the mostly recently executed event.
- * @param time Time until in milliseconds as std::chrono::duration the event occurs.
- */
- void Repeat(Milliseconds const& time)
- {
- Repeat(time.count());
- }
-
- /**
- * @name RepeatEvent
- * @brief Repeats the mostly recently executed event.
- * @param time Time until the event occurs.
- */
- void Repeat(uint32 time)
- {
- _eventMap.insert(EventStore::value_type(_time + time, _lastEvent));
- }
-
- /**
- * @name RepeatEvent
- * @brief Repeats the mostly recently executed event.
- * @param minTime Minimum time as std::chrono::duration until the event occurs.
- * @param maxTime Maximum time as std::chrono::duration until the event occurs.
- */
- void Repeat(Milliseconds const& minTime, Milliseconds const& maxTime)
- {
- Repeat(minTime.count(), maxTime.count());
- }
-
- /**
- * @name RepeatEvent
- * @brief Repeats the mostly recently executed event, Equivalent to Repeat(urand(minTime, maxTime).
- * @param minTime Minimum time until the event occurs.
- * @param maxTime Maximum time until the event occurs.
- */
- void Repeat(uint32 minTime, uint32 maxTime)
- {
- Repeat(urand(minTime, maxTime));
- }
-
- /**
- * @name ExecuteEvent
- * @brief Returns the next event to execute and removes it from map.
- * @return Id of the event to execute.
- */
- uint32 ExecuteEvent();
-
- /**
- * @name DelayEvents
- * @brief Delays all events in the map. If delay is greater than or equal internal timer, delay will be 0.
- * @param delay Amount of delay in ms as std::chrono::duration.
- */
- void DelayEvents(Milliseconds const& delay)
- {
- DelayEvents(delay.count());
- }
-
- /**
- * @name DelayEvents
- * @brief Delays all events in the map. If delay is greater than or equal internal timer, delay will be 0.
- * @param delay Amount of delay.
- */
- void DelayEvents(uint32 delay)
- {
- _time = delay < _time ? _time - delay : 0;
- }
-
- /**
- * @name DelayEvents
- * @brief Delay all events of the same group.
- * @param delay Amount of delay in ms as std::chrono::duration.
- * @param group Group of the events.
- */
- void DelayEvents(Milliseconds const& delay, uint32 group)
- {
- DelayEvents(delay.count(), group);
- }
-
- /**
- * @name DelayEvents
- * @brief Delay all events of the same group.
- * @param delay Amount of delay.
- * @param group Group of the events.
- */
- void DelayEvents(uint32 delay, uint32 group);
-
- /**
- * @name CancelEvent
- * @brief Cancels all events of the specified id.
- * @param eventId Event id to cancel.
- */
- void CancelEvent(uint32 eventId);
-
- /**
- * @name CancelEventGroup
- * @brief Cancel events belonging to specified group.
- * @param group Group to cancel.
- */
- void CancelEventGroup(uint32 group);
-
- /**
- * @name GetNextEventTime
- * @brief Returns closest occurence of specified event.
- * @param eventId Wanted event id.
- * @return Time of found event.
- */
- uint32 GetNextEventTime(uint32 eventId) const;
-
- /**
- * @name GetNextEventTime
- * @return Time of next event.
- */
- uint32 GetNextEventTime() const
- {
- return Empty() ? 0 : _eventMap.begin()->first;
- }
-
- /**
- * @name IsInPhase
- * @brief Returns whether event map is in specified phase or not.
- * @param phase Wanted phase.
- * @return True, if phase of event map contains specified phase.
- */
- bool IsInPhase(uint8 phase) const
- {
- return phase <= 8 && (!phase || _phase & (1 << (phase - 1)));
- }
-
- /**
- * @name GetTimeUntilEvent
- * @brief Returns time in milliseconds until next event.
- * @param eventId of the event.
- * @return Time of next event.
- */
- uint32 GetTimeUntilEvent(uint32 eventId) const;
-
-private:
- /**
- * @name _time
- * @brief Internal timer.
- *
- * This does not represent the real date/time value.
- * It's more like a stopwatch: It can run, it can be stopped,
- * it can be resetted and so on. Events occur when this timer
- * has reached their time value. Its value is changed in the
- * Update method.
- */
- uint32 _time;
-
- /**
- * @name _phase
- * @brief Phase mask of the event map.
- *
- * Contains the phases the event map is in. Multiple
- * phases from 1 to 8 can be set with SetPhase or
- * AddPhase. RemovePhase deactives a phase.
- */
- uint8 _phase;
-
- /**
- * @name _eventMap
- * @brief Internal event storage map. Contains the scheduled events.
- *
- * See typedef at the beginning of the class for more
- * details.
- */
- EventStore _eventMap;
-
- /**
- * @name _lastEvent
- * @brief Stores information on the most recently executed event
- */
- uint32 _lastEvent;
-};
-
-#endif // _EVENT_MAP_H_
diff --git a/src/server/shared/Utilities/EventProcessor.cpp b/src/server/shared/Utilities/EventProcessor.cpp
deleted file mode 100644
index 34695665443..00000000000
--- a/src/server/shared/Utilities/EventProcessor.cpp
+++ /dev/null
@@ -1,99 +0,0 @@
-/*
- * Copyright (C) 2008-2015 TrinityCore <http://www.trinitycore.org/>
- * 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, see <http://www.gnu.org/licenses/>.
- */
-
-#include "EventProcessor.h"
-
-EventProcessor::EventProcessor()
-{
- m_time = 0;
- m_aborting = false;
-}
-
-EventProcessor::~EventProcessor()
-{
- KillAllEvents(true);
-}
-
-void EventProcessor::Update(uint32 p_time)
-{
- // update time
- m_time += p_time;
-
- // main event loop
- EventList::iterator i;
- while (((i = m_events.begin()) != m_events.end()) && i->first <= m_time)
- {
- // get and remove event from queue
- BasicEvent* Event = i->second;
- m_events.erase(i);
-
- if (!Event->to_Abort)
- {
- if (Event->Execute(m_time, p_time))
- {
- // completely destroy event if it is not re-added
- delete Event;
- }
- }
- else
- {
- Event->Abort(m_time);
- delete Event;
- }
- }
-}
-
-void EventProcessor::KillAllEvents(bool force)
-{
- // prevent event insertions
- m_aborting = true;
-
- // first, abort all existing events
- for (EventList::iterator i = m_events.begin(); i != m_events.end();)
- {
- EventList::iterator i_old = i;
- ++i;
-
- i_old->second->to_Abort = true;
- i_old->second->Abort(m_time);
- if (force || i_old->second->IsDeletable())
- {
- delete i_old->second;
-
- if (!force) // need per-element cleanup
- m_events.erase (i_old);
- }
- }
-
- // fast clear event list (in force case)
- if (force)
- m_events.clear();
-}
-
-void EventProcessor::AddEvent(BasicEvent* Event, uint64 e_time, bool set_addtime)
-{
- if (set_addtime) Event->m_addTime = m_time;
- Event->m_execTime = e_time;
- m_events.insert(std::pair<uint64, BasicEvent*>(e_time, Event));
-}
-
-uint64 EventProcessor::CalculateTime(uint64 t_offset) const
-{
- return(m_time + t_offset);
-}
-
diff --git a/src/server/shared/Utilities/EventProcessor.h b/src/server/shared/Utilities/EventProcessor.h
deleted file mode 100644
index 3d54bd6f9f2..00000000000
--- a/src/server/shared/Utilities/EventProcessor.h
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * Copyright (C) 2008-2015 TrinityCore <http://www.trinitycore.org/>
- * 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, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef __EVENTPROCESSOR_H
-#define __EVENTPROCESSOR_H
-
-#include "Define.h"
-
-#include <map>
-
-// Note. All times are in milliseconds here.
-
-class BasicEvent
-{
- public:
- BasicEvent()
- {
- to_Abort = false;
- m_addTime = 0;
- m_execTime = 0;
- }
- virtual ~BasicEvent() { } // override destructor to perform some actions on event removal
-
- // this method executes when the event is triggered
- // return false if event does not want to be deleted
- // e_time is execution time, p_time is update interval
- virtual bool Execute(uint64 /*e_time*/, uint32 /*p_time*/) { return true; }
-
- virtual bool IsDeletable() const { return true; } // this event can be safely deleted
-
- virtual void Abort(uint64 /*e_time*/) { } // this method executes when the event is aborted
-
- bool to_Abort; // set by externals when the event is aborted, aborted events don't execute
- // and get Abort call when deleted
-
- // these can be used for time offset control
- uint64 m_addTime; // time when the event was added to queue, filled by event handler
- uint64 m_execTime; // planned time of next execution, filled by event handler
-};
-
-typedef std::multimap<uint64, BasicEvent*> EventList;
-
-class EventProcessor
-{
- public:
- EventProcessor();
- ~EventProcessor();
-
- void Update(uint32 p_time);
- void KillAllEvents(bool force);
- void AddEvent(BasicEvent* Event, uint64 e_time, bool set_addtime = true);
- uint64 CalculateTime(uint64 t_offset) const;
- protected:
- uint64 m_time;
- EventList m_events;
- bool m_aborting;
-};
-#endif
diff --git a/src/server/shared/Utilities/StringFormat.h b/src/server/shared/Utilities/StringFormat.h
deleted file mode 100644
index 67e0100e7c8..00000000000
--- a/src/server/shared/Utilities/StringFormat.h
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Copyright (C) 2008-2015 TrinityCore <http://www.trinitycore.org/>
- * 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, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef TRINITYCORE_STRING_FORMAT_H
-#define TRINITYCORE_STRING_FORMAT_H
-
-#include "format.h"
-
-namespace Trinity
-{
- /// Default TC string format function.
- template<typename Format, typename... Args>
- inline std::string StringFormat(Format&& fmt, Args&&... args)
- {
- return fmt::sprintf(std::forward<Format>(fmt), std::forward<Args>(args)...);
- }
-
- /// Returns true if the given char pointer is null.
- inline bool IsFormatEmptyOrNull(const char* fmt)
- {
- return fmt == nullptr;
- }
-
- /// Returns true if the given std::string is empty.
- inline bool IsFormatEmptyOrNull(std::string const& fmt)
- {
- return fmt.empty();
- }
-}
-
-#endif
diff --git a/src/server/shared/Utilities/TaskScheduler.cpp b/src/server/shared/Utilities/TaskScheduler.cpp
deleted file mode 100644
index 801cc96cf77..00000000000
--- a/src/server/shared/Utilities/TaskScheduler.cpp
+++ /dev/null
@@ -1,229 +0,0 @@
-/*
- * Copyright (C) 2008-2015 TrinityCore <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, see <http://www.gnu.org/licenses/>.
- */
-
-#include "TaskScheduler.h"
-
-TaskScheduler& TaskScheduler::ClearValidator()
-{
- _predicate = EmptyValidator;
- return *this;
-}
-
-TaskScheduler& TaskScheduler::Update(success_t const& callback)
-{
- _now = clock_t::now();
- Dispatch(callback);
- return *this;
-}
-
-TaskScheduler& TaskScheduler::Update(size_t const milliseconds, success_t const& callback)
-{
- return Update(std::chrono::milliseconds(milliseconds), callback);
-}
-
-TaskScheduler& TaskScheduler::Async(std::function<void()> const& callable)
-{
- _asyncHolder.push(callable);
- return *this;
-}
-
-TaskScheduler& TaskScheduler::CancelAll()
-{
- /// Clear the task holder
- _task_holder.Clear();
- _asyncHolder = AsyncHolder();
- return *this;
-}
-
-TaskScheduler& TaskScheduler::CancelGroup(group_t const group)
-{
- _task_holder.RemoveIf([group](TaskContainer const& task) -> bool
- {
- return task->IsInGroup(group);
- });
- return *this;
-}
-
-TaskScheduler& TaskScheduler::CancelGroupsOf(std::vector<group_t> const& groups)
-{
- std::for_each(groups.begin(), groups.end(),
- std::bind(&TaskScheduler::CancelGroup, this, std::placeholders::_1));
-
- return *this;
-}
-
-TaskScheduler& TaskScheduler::InsertTask(TaskContainer task)
-{
- _task_holder.Push(std::move(task));
- return *this;
-}
-
-void TaskScheduler::Dispatch(success_t const& callback)
-{
- // If the validation failed abort the dispatching here.
- if (!_predicate())
- return;
-
- // Process all asyncs
- while (!_asyncHolder.empty())
- {
- _asyncHolder.front()();
- _asyncHolder.pop();
-
- // If the validation failed abort the dispatching here.
- if (!_predicate())
- return;
- }
-
- while (!_task_holder.IsEmpty())
- {
- if (_task_holder.First()->_end > _now)
- break;
-
- // Perfect forward the context to the handler
- // Use weak references to catch destruction before callbacks.
- TaskContext context(_task_holder.Pop(), std::weak_ptr<TaskScheduler>(self_reference));
-
- // Invoke the context
- context.Invoke();
-
- // If the validation failed abort the dispatching here.
- if (!_predicate())
- return;
- }
-
- // On finish call the final callback
- callback();
-}
-
-void TaskScheduler::TaskQueue::Push(TaskContainer&& task)
-{
- container.insert(task);
-}
-
-auto TaskScheduler::TaskQueue::Pop() -> TaskContainer
-{
- TaskContainer result = *container.begin();
- container.erase(container.begin());
- return result;
-}
-
-auto TaskScheduler::TaskQueue::First() const -> TaskContainer const&
-{
- return *container.begin();
-}
-
-void TaskScheduler::TaskQueue::Clear()
-{
- container.clear();
-}
-
-void TaskScheduler::TaskQueue::RemoveIf(std::function<bool(TaskContainer const&)> const& filter)
-{
- for (auto itr = container.begin(); itr != container.end();)
- if (filter(*itr))
- itr = container.erase(itr);
- else
- ++itr;
-}
-
-void TaskScheduler::TaskQueue::ModifyIf(std::function<bool(TaskContainer const&)> const& filter)
-{
- std::vector<TaskContainer> cache;
- for (auto itr = container.begin(); itr != container.end();)
- if (filter(*itr))
- {
- cache.push_back(*itr);
- itr = container.erase(itr);
- }
- else
- ++itr;
-
- container.insert(cache.begin(), cache.end());
-}
-
-bool TaskScheduler::TaskQueue::IsEmpty() const
-{
- return container.empty();
-}
-
-TaskContext& TaskContext::Dispatch(std::function<TaskScheduler&(TaskScheduler&)> const& apply)
-{
- if (auto const owner = _owner.lock())
- apply(*owner);
-
- return *this;
-}
-
-bool TaskContext::IsExpired() const
-{
- return _owner.expired();
-}
-
-bool TaskContext::IsInGroup(TaskScheduler::group_t const group) const
-{
- return _task->IsInGroup(group);
-}
-
-TaskContext& TaskContext::SetGroup(TaskScheduler::group_t const group)
-{
- _task->_group = group;
- return *this;
-}
-
-TaskContext& TaskContext::ClearGroup()
-{
- _task->_group = boost::none;
- return *this;
-}
-
-TaskScheduler::repeated_t TaskContext::GetRepeatCounter() const
-{
- return _task->_repeated;
-}
-
-TaskContext& TaskContext::Async(std::function<void()> const& callable)
-{
- return Dispatch(std::bind(&TaskScheduler::Async, std::placeholders::_1, callable));
-}
-
-TaskContext& TaskContext::CancelAll()
-{
- return Dispatch(std::mem_fn(&TaskScheduler::CancelAll));
-}
-
-TaskContext& TaskContext::CancelGroup(TaskScheduler::group_t const group)
-{
- return Dispatch(std::bind(&TaskScheduler::CancelGroup, std::placeholders::_1, group));
-}
-
-TaskContext& TaskContext::CancelGroupsOf(std::vector<TaskScheduler::group_t> const& groups)
-{
- return Dispatch(std::bind(&TaskScheduler::CancelGroupsOf, std::placeholders::_1, std::cref(groups)));
-}
-
-void TaskContext::AssertOnConsumed() const
-{
- // This was adapted to TC to prevent static analysis tools from complaining.
- // If you encounter this assertion check if you repeat a TaskContext more then 1 time!
- ASSERT(!(*_consumed) && "Bad task logic, task context was consumed already!");
-}
-
-void TaskContext::Invoke()
-{
- _task->_task(*this);
-}
diff --git a/src/server/shared/Utilities/TaskScheduler.h b/src/server/shared/Utilities/TaskScheduler.h
deleted file mode 100644
index f1fe7ea0a21..00000000000
--- a/src/server/shared/Utilities/TaskScheduler.h
+++ /dev/null
@@ -1,650 +0,0 @@
-/*
- * Copyright (C) 2008-2015 TrinityCore <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, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef _TASK_SCHEDULER_H_
-#define _TASK_SCHEDULER_H_
-
-#include <algorithm>
-#include <chrono>
-#include <vector>
-#include <queue>
-#include <memory>
-#include <utility>
-#include <set>
-
-#include <boost/optional.hpp>
-
-#include "Util.h"
-#include "Duration.h"
-
-class TaskContext;
-
-/// The TaskScheduler class provides the ability to schedule std::function's in the near future.
-/// Use TaskScheduler::Update to update the scheduler.
-/// Popular methods are:
-/// * Schedule (Schedules a std::function which will be executed in the near future).
-/// * Schedules an asynchronous function which will be executed at the next update tick.
-/// * Cancel, Delay & Reschedule (Methods to manipulate already scheduled tasks).
-/// Tasks are organized in groups (uint), multiple tasks can have the same group id,
-/// you can provide a group or not, but keep in mind that you can only manipulate specific tasks through its group id!
-/// Tasks callbacks use the function signature void(TaskContext) where TaskContext provides
-/// access to the function schedule plan which makes it possible to repeat the task
-/// with the same duration or a new one.
-/// It also provides access to the repeat counter which is useful for task that repeat itself often
-/// but behave different every time (spoken event dialogs for example).
-class TaskScheduler
-{
- friend class TaskContext;
-
- // Time definitions (use steady clock)
- typedef std::chrono::steady_clock clock_t;
- typedef clock_t::time_point timepoint_t;
- typedef clock_t::duration duration_t;
-
- // Task group type
- typedef uint32 group_t;
- // Task repeated type
- typedef uint32 repeated_t;
- // Task handle type
- typedef std::function<void(TaskContext)> task_handler_t;
- // Predicate type
- typedef std::function<bool()> predicate_t;
- // Success handle type
- typedef std::function<void()> success_t;
-
- class Task
- {
- friend class TaskContext;
- friend class TaskScheduler;
-
- timepoint_t _end;
- duration_t _duration;
- boost::optional<group_t> _group;
- repeated_t _repeated;
- task_handler_t _task;
-
- public:
- // All Argument construct
- Task(timepoint_t const& end, duration_t const& duration, boost::optional<group_t> const& group,
- repeated_t const repeated, task_handler_t const& task)
- : _end(end), _duration(duration), _group(group), _repeated(repeated), _task(task) { }
-
- // Minimal Argument construct
- Task(timepoint_t const& end, duration_t const& duration, task_handler_t const& task)
- : _end(end), _duration(duration), _group(boost::none), _repeated(0), _task(task) { }
-
- // Copy construct
- Task(Task const&) = delete;
- // Move construct
- Task(Task&&) = delete;
- // Copy Assign
- Task& operator= (Task const&) = default;
- // Move Assign
- Task& operator= (Task&& right) = delete;
-
- // Order tasks by its end
- inline bool operator< (Task const& other) const
- {
- return _end < other._end;
- }
-
- inline bool operator> (Task const& other) const
- {
- return _end > other._end;
- }
-
- // Compare tasks with its end
- inline bool operator== (Task const& other)
- {
- return _end == other._end;
- }
-
- // Returns true if the task is in the given group
- inline bool IsInGroup(group_t const group) const
- {
- return _group == group;
- }
- };
-
- typedef std::shared_ptr<Task> TaskContainer;
-
- /// Container which provides Task order, insert and reschedule operations.
- struct Compare
- {
- bool operator() (TaskContainer const& left, TaskContainer const& right)
- {
- return (*left.get()) < (*right.get());
- };
- };
-
- class TaskQueue
- {
- std::multiset<TaskContainer, Compare> container;
-
- public:
- // Pushes the task in the container
- void Push(TaskContainer&& task);
-
- /// Pops the task out of the container
- TaskContainer Pop();
-
- TaskContainer const& First() const;
-
- void Clear();
-
- void RemoveIf(std::function<bool(TaskContainer const&)> const& filter);
-
- void ModifyIf(std::function<bool(TaskContainer const&)> const& filter);
-
- bool IsEmpty() const;
- };
-
- /// Contains a self reference to track if this object was deleted or not.
- std::shared_ptr<TaskScheduler> self_reference;
-
- /// The current time point (now)
- timepoint_t _now;
-
- /// The Task Queue which contains all task objects.
- TaskQueue _task_holder;
-
- typedef std::queue<std::function<void()>> AsyncHolder;
-
- /// Contains all asynchronous tasks which will be invoked at
- /// the next update tick.
- AsyncHolder _asyncHolder;
-
- predicate_t _predicate;
-
- static bool EmptyValidator()
- {
- return true;
- }
-
- static void EmptyCallback()
- {
- }
-
-public:
- TaskScheduler()
- : self_reference(this, [](TaskScheduler const*) { }), _now(clock_t::now()), _predicate(EmptyValidator) { }
-
- template<typename P>
- TaskScheduler(P&& predicate)
- : self_reference(this, [](TaskScheduler const*) { }), _now(clock_t::now()), _predicate(std::forward<P>(predicate)) { }
-
- TaskScheduler(TaskScheduler const&) = delete;
- TaskScheduler(TaskScheduler&&) = delete;
- TaskScheduler& operator= (TaskScheduler const&) = delete;
- TaskScheduler& operator= (TaskScheduler&&) = delete;
-
- /// Sets a validator which is asked if tasks are allowed to be executed.
- template<typename P>
- TaskScheduler& SetValidator(P&& predicate)
- {
- _predicate = std::forward<P>(predicate);
- return *this;
- }
-
- /// Clears the validator which is asked if tasks are allowed to be executed.
- TaskScheduler& ClearValidator();
-
- /// Update the scheduler to the current time.
- /// Calls the optional callback on successfully finish.
- TaskScheduler& Update(success_t const& callback = EmptyCallback);
-
- /// Update the scheduler with a difftime in ms.
- /// Calls the optional callback on successfully finish.
- TaskScheduler& Update(size_t const milliseconds, success_t const& callback = EmptyCallback);
-
- /// Update the scheduler with a difftime.
- /// Calls the optional callback on successfully finish.
- template<class _Rep, class _Period>
- TaskScheduler& Update(std::chrono::duration<_Rep, _Period> const& difftime,
- success_t const& callback = EmptyCallback)
- {
- _now += difftime;
- Dispatch(callback);
- return *this;
- }
-
- /// Schedule an callable function that is executed at the next update tick.
- /// Its safe to modify the TaskScheduler from within the callable.
- TaskScheduler& Async(std::function<void()> const& callable);
-
- /// Schedule an event with a fixed rate.
- /// Never call this from within a task context! Use TaskContext::Schedule instead!
- template<class _Rep, class _Period>
- TaskScheduler& Schedule(std::chrono::duration<_Rep, _Period> const& time,
- task_handler_t const& task)
- {
- return ScheduleAt(_now, time, task);
- }
-
- /// Schedule an event with a fixed rate.
- /// Never call this from within a task context! Use TaskContext::Schedule instead!
- template<class _Rep, class _Period>
- TaskScheduler& Schedule(std::chrono::duration<_Rep, _Period> const& time,
- group_t const group, task_handler_t const& task)
- {
- return ScheduleAt(_now, time, group, task);
- }
-
- /// Schedule an event with a randomized rate between min and max rate.
- /// Never call this from within a task context! Use TaskContext::Schedule instead!
- template<class _RepLeft, class _PeriodLeft, class _RepRight, class _PeriodRight>
- TaskScheduler& Schedule(std::chrono::duration<_RepLeft, _PeriodLeft> const& min,
- std::chrono::duration<_RepRight, _PeriodRight> const& max, task_handler_t const& task)
- {
- return Schedule(RandomDurationBetween(min, max), task);
- }
-
- /// Schedule an event with a fixed rate.
- /// Never call this from within a task context! Use TaskContext::Schedule instead!
- template<class _RepLeft, class _PeriodLeft, class _RepRight, class _PeriodRight>
- TaskScheduler& Schedule(std::chrono::duration<_RepLeft, _PeriodLeft> const& min,
- std::chrono::duration<_RepRight, _PeriodRight> const& max, group_t const group,
- task_handler_t const& task)
- {
- return Schedule(RandomDurationBetween(min, max), group, task);
- }
-
- /// Cancels all tasks.
- /// Never call this from within a task context! Use TaskContext::CancelAll instead!
- TaskScheduler& CancelAll();
-
- /// Cancel all tasks of a single group.
- /// Never call this from within a task context! Use TaskContext::CancelGroup instead!
- TaskScheduler& CancelGroup(group_t const group);
-
- /// Cancels all groups in the given std::vector.
- /// Hint: Use std::initializer_list for this: "{1, 2, 3, 4}"
- TaskScheduler& CancelGroupsOf(std::vector<group_t> const& groups);
-
- /// Delays all tasks with the given duration.
- template<class _Rep, class _Period>
- TaskScheduler& DelayAll(std::chrono::duration<_Rep, _Period> const& duration)
- {
- _task_holder.ModifyIf([&duration](TaskContainer const& task) -> bool
- {
- task->_end += duration;
- return true;
- });
- return *this;
- }
-
- /// Delays all tasks with a random duration between min and max.
- template<class _RepLeft, class _PeriodLeft, class _RepRight, class _PeriodRight>
- TaskScheduler& DelayAll(std::chrono::duration<_RepLeft, _PeriodLeft> const& min,
- std::chrono::duration<_RepRight, _PeriodRight> const& max)
- {
- return DelayAll(RandomDurationBetween(min, max));
- }
-
- /// Delays all tasks of a group with the given duration.
- template<class _Rep, class _Period>
- TaskScheduler& DelayGroup(group_t const group, std::chrono::duration<_Rep, _Period> const& duration)
- {
- _task_holder.ModifyIf([&duration, group](TaskContainer const& task) -> bool
- {
- if (task->IsInGroup(group))
- {
- task->_end += duration;
- return true;
- }
- else
- return false;
- });
- return *this;
- }
-
- /// Delays all tasks of a group with a random duration between min and max.
- template<class _RepLeft, class _PeriodLeft, class _RepRight, class _PeriodRight>
- TaskScheduler& DelayGroup(group_t const group,
- std::chrono::duration<_RepLeft, _PeriodLeft> const& min,
- std::chrono::duration<_RepRight, _PeriodRight> const& max)
- {
- return DelayGroup(group, RandomDurationBetween(min, max));
- }
-
- /// Reschedule all tasks with a given duration.
- template<class _Rep, class _Period>
- TaskScheduler& RescheduleAll(std::chrono::duration<_Rep, _Period> const& duration)
- {
- auto const end = _now + duration;
- _task_holder.ModifyIf([end](TaskContainer const& task) -> bool
- {
- task->_end = end;
- return true;
- });
- return *this;
- }
-
- /// Reschedule all tasks with a random duration between min and max.
- template<class _RepLeft, class _PeriodLeft, class _RepRight, class _PeriodRight>
- TaskScheduler& RescheduleAll(std::chrono::duration<_RepLeft, _PeriodLeft> const& min,
- std::chrono::duration<_RepRight, _PeriodRight> const& max)
- {
- return RescheduleAll(RandomDurationBetween(min, max));
- }
-
- /// Reschedule all tasks of a group with the given duration.
- template<class _Rep, class _Period>
- TaskScheduler& RescheduleGroup(group_t const group, std::chrono::duration<_Rep, _Period> const& duration)
- {
- auto const end = _now + duration;
- _task_holder.ModifyIf([end, group](TaskContainer const& task) -> bool
- {
- if (task->IsInGroup(group))
- {
- task->_end = end;
- return true;
- }
- else
- return false;
- });
- return *this;
- }
-
- /// Reschedule all tasks of a group with a random duration between min and max.
- template<class _RepLeft, class _PeriodLeft, class _RepRight, class _PeriodRight>
- TaskScheduler& RescheduleGroup(group_t const group,
- std::chrono::duration<_RepLeft, _PeriodLeft> const& min,
- std::chrono::duration<_RepRight, _PeriodRight> const& max)
- {
- return RescheduleGroup(group, RandomDurationBetween(min, max));
- }
-
-private:
- /// Insert a new task to the enqueued tasks.
- TaskScheduler& InsertTask(TaskContainer task);
-
- template<class _Rep, class _Period>
- TaskScheduler& ScheduleAt(timepoint_t const& end,
- std::chrono::duration<_Rep, _Period> const& time, task_handler_t const& task)
- {
- return InsertTask(TaskContainer(new Task(end + time, time, task)));
- }
-
- /// Schedule an event with a fixed rate.
- /// Never call this from within a task context! Use TaskContext::schedule instead!
- template<class _Rep, class _Period>
- TaskScheduler& ScheduleAt(timepoint_t const& end,
- std::chrono::duration<_Rep, _Period> const& time,
- group_t const group, task_handler_t const& task)
- {
- static repeated_t const DEFAULT_REPEATED = 0;
- return InsertTask(TaskContainer(new Task(end + time, time, group, DEFAULT_REPEATED, task)));
- }
-
- // Returns a random duration between min and max
- template<class _RepLeft, class _PeriodLeft, class _RepRight, class _PeriodRight>
- static std::chrono::milliseconds
- RandomDurationBetween(std::chrono::duration<_RepLeft, _PeriodLeft> const& min,
- std::chrono::duration<_RepRight, _PeriodRight> const& max)
- {
- auto const milli_min = std::chrono::duration_cast<std::chrono::milliseconds>(min);
- auto const milli_max = std::chrono::duration_cast<std::chrono::milliseconds>(max);
-
- // TC specific: use SFMT URandom
- return std::chrono::milliseconds(urand(milli_min.count(), milli_max.count()));
- }
-
- /// Dispatch remaining tasks
- void Dispatch(success_t const& callback);
-};
-
-class TaskContext
-{
- friend class TaskScheduler;
-
- /// Associated task
- TaskScheduler::TaskContainer _task;
-
- /// Owner
- std::weak_ptr<TaskScheduler> _owner;
-
- /// Marks the task as consumed
- std::shared_ptr<bool> _consumed;
-
- /// Dispatches an action safe on the TaskScheduler
- TaskContext& Dispatch(std::function<TaskScheduler&(TaskScheduler&)> const& apply);
-
-public:
- // Empty constructor
- TaskContext()
- : _task(), _owner(), _consumed(std::make_shared<bool>(true)) { }
-
- // Construct from task and owner
- explicit TaskContext(TaskScheduler::TaskContainer&& task, std::weak_ptr<TaskScheduler>&& owner)
- : _task(task), _owner(owner), _consumed(std::make_shared<bool>(false)) { }
-
- // Copy construct
- TaskContext(TaskContext const& right)
- : _task(right._task), _owner(right._owner), _consumed(right._consumed) { }
-
- // Move construct
- TaskContext(TaskContext&& right)
- : _task(std::move(right._task)), _owner(std::move(right._owner)), _consumed(std::move(right._consumed)) { }
-
- // Copy assign
- TaskContext& operator= (TaskContext const& right)
- {
- _task = right._task;
- _owner = right._owner;
- _consumed = right._consumed;
- return *this;
- }
-
- // Move assign
- TaskContext& operator= (TaskContext&& right)
- {
- _task = std::move(right._task);
- _owner = std::move(right._owner);
- _consumed = std::move(right._consumed);
- return *this;
- }
-
- /// Returns true if the owner was deallocated and this context has expired.
- bool IsExpired() const;
-
- /// Returns true if the event is in the given group
- bool IsInGroup(TaskScheduler::group_t const group) const;
-
- /// Sets the event in the given group
- TaskContext& SetGroup(TaskScheduler::group_t const group);
-
- /// Removes the group from the event
- TaskContext& ClearGroup();
-
- /// Returns the repeat counter which increases every time the task is repeated.
- TaskScheduler::repeated_t GetRepeatCounter() const;
-
- /// Repeats the event and sets a new duration.
- /// std::chrono::seconds(5) for example.
- /// This will consume the task context, its not possible to repeat the task again
- /// from the same task context!
- template<class _Rep, class _Period>
- TaskContext& Repeat(std::chrono::duration<_Rep, _Period> const& duration)
- {
- AssertOnConsumed();
-
- // Set new duration, in-context timing and increment repeat counter
- _task->_duration = duration;
- _task->_end += duration;
- _task->_repeated += 1;
- (*_consumed) = true;
- return Dispatch(std::bind(&TaskScheduler::InsertTask, std::placeholders::_1, _task));
- }
-
- /// Repeats the event with the same duration.
- /// This will consume the task context, its not possible to repeat the task again
- /// from the same task context!
- TaskContext& Repeat()
- {
- return Repeat(_task->_duration);
- }
-
- /// Repeats the event and set a new duration that is randomized between min and max.
- /// std::chrono::seconds(5) for example.
- /// This will consume the task context, its not possible to repeat the task again
- /// from the same task context!
- template<class _RepLeft, class _PeriodLeft, class _RepRight, class _PeriodRight>
- TaskContext& Repeat(std::chrono::duration<_RepLeft, _PeriodLeft> const& min,
- std::chrono::duration<_RepRight, _PeriodRight> const& max)
- {
- return Repeat(TaskScheduler::RandomDurationBetween(min, max));
- }
-
- /// Schedule a callable function that is executed at the next update tick from within the context.
- /// Its safe to modify the TaskScheduler from within the callable.
- TaskContext& Async(std::function<void()> const& callable);
-
- /// Schedule an event with a fixed rate from within the context.
- /// Its possible that the new event is executed immediately!
- /// Use TaskScheduler::Async to create a task
- /// which will be called at the next update tick.
- template<class _Rep, class _Period>
- TaskContext& Schedule(std::chrono::duration<_Rep, _Period> const& time,
- TaskScheduler::task_handler_t const& task)
- {
- auto const end = _task->_end;
- return Dispatch([end, time, task](TaskScheduler& scheduler) -> TaskScheduler&
- {
- return scheduler.ScheduleAt<_Rep, _Period>(end, time, task);
- });
- }
-
- /// Schedule an event with a fixed rate from within the context.
- /// Its possible that the new event is executed immediately!
- /// Use TaskScheduler::Async to create a task
- /// which will be called at the next update tick.
- template<class _Rep, class _Period>
- TaskContext& Schedule(std::chrono::duration<_Rep, _Period> const& time,
- TaskScheduler::group_t const group, TaskScheduler::task_handler_t const& task)
- {
- auto const end = _task->_end;
- return Dispatch([end, time, group, task](TaskScheduler& scheduler) -> TaskScheduler&
- {
- return scheduler.ScheduleAt<_Rep, _Period>(end, time, group, task);
- });
- }
-
- /// Schedule an event with a randomized rate between min and max rate from within the context.
- /// Its possible that the new event is executed immediately!
- /// Use TaskScheduler::Async to create a task
- /// which will be called at the next update tick.
- template<class _RepLeft, class _PeriodLeft, class _RepRight, class _PeriodRight>
- TaskContext& Schedule(std::chrono::duration<_RepLeft, _PeriodLeft> const& min,
- std::chrono::duration<_RepRight, _PeriodRight> const& max, TaskScheduler::task_handler_t const& task)
- {
- return Schedule(TaskScheduler::RandomDurationBetween(min, max), task);
- }
-
- /// Schedule an event with a randomized rate between min and max rate from within the context.
- /// Its possible that the new event is executed immediately!
- /// Use TaskScheduler::Async to create a task
- /// which will be called at the next update tick.
- template<class _RepLeft, class _PeriodLeft, class _RepRight, class _PeriodRight>
- TaskContext& Schedule(std::chrono::duration<_RepLeft, _PeriodLeft> const& min,
- std::chrono::duration<_RepRight, _PeriodRight> const& max, TaskScheduler::group_t const group,
- TaskScheduler::task_handler_t const& task)
- {
- return Schedule(TaskScheduler::RandomDurationBetween(min, max), group, task);
- }
-
- /// Cancels all tasks from within the context.
- TaskContext& CancelAll();
-
- /// Cancel all tasks of a single group from within the context.
- TaskContext& CancelGroup(TaskScheduler::group_t const group);
-
- /// Cancels all groups in the given std::vector from within the context.
- /// Hint: Use std::initializer_list for this: "{1, 2, 3, 4}"
- TaskContext& CancelGroupsOf(std::vector<TaskScheduler::group_t> const& groups);
-
- /// Delays all tasks with the given duration from within the context.
- template<class _Rep, class _Period>
- TaskContext& DelayAll(std::chrono::duration<_Rep, _Period> const& duration)
- {
- return Dispatch(std::bind(&TaskScheduler::DelayAll<_Rep, _Period>, std::placeholders::_1, duration));
- }
-
- /// Delays all tasks with a random duration between min and max from within the context.
- template<class _RepLeft, class _PeriodLeft, class _RepRight, class _PeriodRight>
- TaskContext& DelayAll(std::chrono::duration<_RepLeft, _PeriodLeft> const& min,
- std::chrono::duration<_RepRight, _PeriodRight> const& max)
- {
- return DelayAll(TaskScheduler::RandomDurationBetween(min, max));
- }
-
- /// Delays all tasks of a group with the given duration from within the context.
- template<class _Rep, class _Period>
- TaskContext& DelayGroup(TaskScheduler::group_t const group, std::chrono::duration<_Rep, _Period> const& duration)
- {
- return Dispatch(std::bind(&TaskScheduler::DelayGroup<_Rep, _Period>, std::placeholders::_1, group, duration));
- }
-
- /// Delays all tasks of a group with a random duration between min and max from within the context.
- template<class _RepLeft, class _PeriodLeft, class _RepRight, class _PeriodRight>
- TaskContext& DelayGroup(TaskScheduler::group_t const group,
- std::chrono::duration<_RepLeft, _PeriodLeft> const& min,
- std::chrono::duration<_RepRight, _PeriodRight> const& max)
- {
- return DelayGroup(group, TaskScheduler::RandomDurationBetween(min, max));
- }
-
- /// Reschedule all tasks with the given duration.
- template<class _Rep, class _Period>
- TaskContext& RescheduleAll(std::chrono::duration<_Rep, _Period> const& duration)
- {
- return Dispatch(std::bind(&TaskScheduler::RescheduleAll, std::placeholders::_1, duration));
- }
-
- /// Reschedule all tasks with a random duration between min and max.
- template<class _RepLeft, class _PeriodLeft, class _RepRight, class _PeriodRight>
- TaskContext& RescheduleAll(std::chrono::duration<_RepLeft, _PeriodLeft> const& min,
- std::chrono::duration<_RepRight, _PeriodRight> const& max)
- {
- return RescheduleAll(TaskScheduler::RandomDurationBetween(min, max));
- }
-
- /// Reschedule all tasks of a group with the given duration.
- template<class _Rep, class _Period>
- TaskContext& RescheduleGroup(TaskScheduler::group_t const group, std::chrono::duration<_Rep, _Period> const& duration)
- {
- return Dispatch(std::bind(&TaskScheduler::RescheduleGroup<_Rep, _Period>, std::placeholders::_1, group, duration));
- }
-
- /// Reschedule all tasks of a group with a random duration between min and max.
- template<class _RepLeft, class _PeriodLeft, class _RepRight, class _PeriodRight>
- TaskContext& RescheduleGroup(TaskScheduler::group_t const group,
- std::chrono::duration<_RepLeft, _PeriodLeft> const& min,
- std::chrono::duration<_RepRight, _PeriodRight> const& max)
- {
- return RescheduleGroup(group, TaskScheduler::RandomDurationBetween(min, max));
- }
-
-private:
- /// Asserts if the task was consumed already.
- void AssertOnConsumed() const;
-
- /// Invokes the associated hook of the task.
- void Invoke();
-};
-
-#endif /// _TASK_SCHEDULER_H_
diff --git a/src/server/shared/Utilities/Timer.h b/src/server/shared/Utilities/Timer.h
deleted file mode 100644
index c54903d7be2..00000000000
--- a/src/server/shared/Utilities/Timer.h
+++ /dev/null
@@ -1,203 +0,0 @@
-/*
- * Copyright (C) 2008-2015 TrinityCore <http://www.trinitycore.org/>
- * 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, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef TRINITY_TIMER_H
-#define TRINITY_TIMER_H
-
-#include <chrono>
-
-inline uint32 getMSTime()
-{
- using namespace std::chrono;
-
- static const system_clock::time_point ApplicationStartTime = system_clock::now();
-
- return uint32(duration_cast<milliseconds>(system_clock::now() - ApplicationStartTime).count());
-}
-
-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;
-}
-
-inline uint32 GetMSTimeDiffToNow(uint32 oldMSTime)
-{
- return getMSTimeDiff(oldMSTime, getMSTime());
-}
-
-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 = 0)
- : 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_period(period), i_expireTime(start_time)
- {
- }
-
- bool Update(const uint32 diff)
- {
- if ((i_expireTime -= diff) > 0)
- return false;
-
- i_expireTime += i_period > int32(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
diff --git a/src/server/shared/Utilities/Util.cpp b/src/server/shared/Utilities/Util.cpp
deleted file mode 100644
index 33c273fb05f..00000000000
--- a/src/server/shared/Utilities/Util.cpp
+++ /dev/null
@@ -1,562 +0,0 @@
-/*
- * Copyright (C) 2008-2015 TrinityCore <http://www.trinitycore.org/>
- * 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, see <http://www.gnu.org/licenses/>.
- */
-
-#include "Util.h"
-#include "Common.h"
-#include "CompilerDefs.h"
-#include "utf8.h"
-#include "SFMT.h"
-#include "Errors.h" // for ASSERT
-#include <stdarg.h>
-#include <boost/thread/tss.hpp>
-
-#if COMPILER == COMPILER_GNU
- #include <sys/socket.h>
- #include <netinet/in.h>
- #include <arpa/inet.h>
-#endif
-
-static boost::thread_specific_ptr<SFMTRand> sfmtRand;
-
-static SFMTRand* GetRng()
-{
- SFMTRand* rand = sfmtRand.get();
-
- if (!rand)
- {
- rand = new SFMTRand();
- sfmtRand.reset(rand);
- }
-
- return rand;
-}
-
-int32 irand(int32 min, int32 max)
-{
- ASSERT(max >= min);
- return int32(GetRng()->IRandom(min, max));
-}
-
-uint32 urand(uint32 min, uint32 max)
-{
- ASSERT(max >= min);
- return GetRng()->URandom(min, max);
-}
-
-float frand(float min, float max)
-{
- ASSERT(max >= min);
- return float(GetRng()->Random() * (max - min) + min);
-}
-
-uint32 rand32()
-{
- return GetRng()->BRandom();
-}
-
-double rand_norm()
-{
- return GetRng()->Random();
-}
-
-double rand_chance()
-{
- return GetRng()->Random() * 100.0;
-}
-
-Tokenizer::Tokenizer(const std::string &src, const char sep, uint32 vectorReserve)
-{
- m_str = new char[src.length() + 1];
- memcpy(m_str, src.c_str(), src.length() + 1);
-
- if (vectorReserve)
- m_storage.reserve(vectorReserve);
-
- char* posold = m_str;
- char* posnew = m_str;
-
- for (;;)
- {
- if (*posnew == sep)
- {
- m_storage.push_back(posold);
- posold = posnew + 1;
-
- *posnew = '\0';
- }
- else if (*posnew == '\0')
- {
- // Hack like, but the old code accepted these kind of broken strings,
- // so changing it would break other things
- if (posold != posnew)
- m_storage.push_back(posold);
-
- break;
- }
-
- ++posnew;
- }
-}
-
-void stripLineInvisibleChars(std::string &str)
-{
- static std::string const 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();
-
-}
-
-#if (defined(WIN32) || defined(_WIN32) || defined(__WIN32__))
-struct tm* localtime_r(const time_t* time, struct tm *result)
-{
- localtime_s(result, time);
- return result;
-}
-#endif
-
-std::string secsToTimeString(uint64 timeInSecs, bool shortText, bool hoursOnly)
-{
- uint64 secs = timeInSecs % MINUTE;
- uint64 minutes = timeInSecs % HOUR / MINUTE;
- uint64 hours = timeInSecs % DAY / HOUR;
- uint64 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();
-}
-
-int32 MoneyStringToMoney(const std::string& moneyString)
-{
- int32 money = 0;
-
- if (!(std::count(moneyString.begin(), moneyString.end(), 'g') == 1 ||
- std::count(moneyString.begin(), moneyString.end(), 's') == 1 ||
- std::count(moneyString.begin(), moneyString.end(), 'c') == 1))
- return 0; // Bad format
-
- Tokenizer tokens(moneyString, ' ');
- for (Tokenizer::const_iterator itr = tokens.begin(); itr != tokens.end(); ++itr)
- {
- std::string tokenString(*itr);
- size_t gCount = std::count(tokenString.begin(), tokenString.end(), 'g');
- size_t sCount = std::count(tokenString.begin(), tokenString.end(), 's');
- size_t cCount = std::count(tokenString.begin(), tokenString.end(), 'c');
- if (gCount + sCount + cCount != 1)
- return 0;
-
- uint32 amount = atoi(*itr);
- if (gCount == 1)
- money += amount * 100 * 100;
- else if (sCount == 1)
- money += amount * 100;
- else if (cCount == 1)
- money += amount;
- }
-
- return money;
-}
-
-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_r(&t, &aTm);
- // 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, "%u", 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.clear();
- 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.clear();
- }
-}
-
-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
- {
- if (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.clear();
- 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
-
- if (size)
- {
- char* oend = utf8::utf16to8(wstr, wstr+size, &utf8str2[0]);
- utf8str2.resize(oend-(&utf8str2[0])); // remove unused tail
- }
- utf8str = utf8str2;
- }
- catch(std::exception)
- {
- utf8str.clear();
- return false;
- }
-
- return true;
-}
-
-bool WStrToUtf8(std::wstring const& wstr, std::string& utf8str)
-{
- try
- {
- std::string utf8str2;
- utf8str2.resize(wstr.size()*4); // allocate for most long case
-
- if (wstr.size())
- {
- 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.clear();
- return false;
- }
-
- return true;
-}
-
-typedef wchar_t const* const* wstrlist;
-
-std::wstring GetMainPartOfName(std::wstring const& 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 const& 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);
- //vsnprintf returns -1 if the buffer is too small
- if (temp_len == size_t(-1))
- temp_len = 32*1024-1;
-
- 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, "%s", temp_buf);
-#else
- vfprintf(out, str, *ap);
-#endif
-}
-
-std::string ByteArrayToHexStr(uint8 const* bytes, uint32 arrayLen, bool reverse /* = false */)
-{
- int32 init = 0;
- int32 end = arrayLen;
- int8 op = 1;
-
- if (reverse)
- {
- init = arrayLen - 1;
- end = -1;
- op = -1;
- }
-
- std::ostringstream ss;
- for (int32 i = init; i != end; i += op)
- {
- char buffer[4];
- sprintf(buffer, "%02X", bytes[i]);
- ss << buffer;
- }
-
- return ss.str();
-}
diff --git a/src/server/shared/Utilities/Util.h b/src/server/shared/Utilities/Util.h
deleted file mode 100644
index 3da1c800410..00000000000
--- a/src/server/shared/Utilities/Util.h
+++ /dev/null
@@ -1,545 +0,0 @@
-/*
- * Copyright (C) 2008-2015 TrinityCore <http://www.trinitycore.org/>
- * 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, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef _UTIL_H
-#define _UTIL_H
-
-#include "Define.h"
-#include "Errors.h"
-
-#include <algorithm>
-#include <string>
-#include <vector>
-#include <list>
-#include <map>
-
-// Searcher for map of structs
-template<typename T, class S> struct Finder
-{
- T val_;
- T S::* idMember_;
-
- Finder(T val, T S::* idMember) : val_(val), idMember_(idMember) {}
- bool operator()(const std::pair<int, S> &obj) { return obj.second.*idMember_ == val_; }
-};
-
-class Tokenizer
-{
-public:
- typedef std::vector<char const*> StorageType;
-
- typedef StorageType::size_type size_type;
-
- typedef StorageType::const_iterator const_iterator;
- typedef StorageType::reference reference;
- typedef StorageType::const_reference const_reference;
-
-public:
- Tokenizer(const std::string &src, char const sep, uint32 vectorReserve = 0);
- ~Tokenizer() { delete[] m_str; }
-
- const_iterator begin() const { return m_storage.begin(); }
- const_iterator end() const { return m_storage.end(); }
-
- size_type size() const { return m_storage.size(); }
-
- reference operator [] (size_type i) { return m_storage[i]; }
- const_reference operator [] (size_type i) const { return m_storage[i]; }
-
-private:
- char* m_str;
- StorageType m_storage;
-};
-
-void stripLineInvisibleChars(std::string &src);
-
-int32 MoneyStringToMoney(const std::string& moneyString);
-
-struct tm* localtime_r(const time_t* time, struct tm *result);
-
-std::string secsToTimeString(uint64 timeInSecs, bool shortText = false, bool hoursOnly = false);
-uint32 TimeStringToSecs(const std::string& timestring);
-std::string TimeToTimestampStr(time_t t);
-
-/* Return a random number in the range min..max. */
-int32 irand(int32 min, int32 max);
-
-/* Return a random number in the range min..max (inclusive). */
-uint32 urand(uint32 min, uint32 max);
-
-/* Return a random number in the range 0 .. UINT32_MAX. */
-uint32 rand32();
-
-/* Return a random number in the range min..max */
-float frand(float min, float max);
-
-/* Return a random double from 0.0 to 1.0 (exclusive). */
-double rand_norm();
-
-/* Return a random double from 0.0 to 100.0 (exclusive). */
-double rand_chance();
-
-/* 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 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));
-}
-
-// Percentage calculation
-template <class T, class U>
-inline T CalculatePct(T base, U pct)
-{
- return T(base * static_cast<float>(pct) / 100.0f);
-}
-
-template <class T, class U>
-inline T AddPct(T &base, U pct)
-{
- return base += CalculatePct(base, pct);
-}
-
-template <class T, class U>
-inline T ApplyPct(T &base, U pct)
-{
- return base = CalculatePct(base, pct);
-}
-
-template <class T>
-inline T RoundToInterval(T& num, T floor, T ceil)
-{
- return num = std::min(std::max(num, floor), ceil);
-}
-
-// UTF8 handling
-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 const& 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 <= 0x00DE) // 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 isNumeric(char const* str)
-{
- for (char const* c = str; *c; ++c)
- if (!isNumeric(*c))
- return false;
-
- return true;
-}
-
-inline bool isNumericOrSpace(wchar_t wchar)
-{
- return isNumeric(wchar) || wchar == L' ';
-}
-
-inline bool isBasicLatinString(const 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(const 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(const 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(const 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 const& 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 const& 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);
-
-std::string ByteArrayToHexStr(uint8 const* bytes, uint32 length, bool reverse = false);
-
-// simple class for not-modifyable list
-template <typename T>
-class HookList
-{
- typedef typename std::list<T>::iterator ListIterator;
- private:
- typename std::list<T> m_list;
- public:
- HookList<T> & operator+=(T t)
- {
- m_list.push_back(t);
- return *this;
- }
- HookList<T> & operator-=(T t)
- {
- m_list.remove(t);
- return *this;
- }
- size_t size()
- {
- return m_list.size();
- }
- ListIterator begin()
- {
- return m_list.begin();
- }
- ListIterator end()
- {
- return m_list.end();
- }
-};
-
-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;
- }
-
- 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;
- }
-
- inline bool operator <(const flag96 &right) const
- {
- for (uint8 i = 3; i > 0; --i)
- {
- if (part[i - 1] < right.part[i - 1])
- return true;
- else if (part[i - 1] > right.part[i - 1])
- return false;
- }
- return false;
- }
-
- inline bool operator ==(const flag96 &right) const
- {
- return
- (
- part[0] == right.part[0] &&
- part[1] == right.part[1] &&
- part[2] == right.part[2]
- );
- }
-
- inline bool operator !=(const flag96 &right) const
- {
- return !this->operator ==(right);
- }
-
- inline flag96 & operator =(const flag96 &right)
- {
- part[0] = right.part[0];
- part[1] = right.part[1];
- part[2] = right.part[2];
- return *this;
- }
-
- inline flag96 operator &(const flag96 &right) const
- {
- return flag96(part[0] & right.part[0], part[1] & right.part[1],
- part[2] & right.part[2]);
- }
-
- inline flag96 & operator &=(const flag96 &right)
- {
- part[0] &= right.part[0];
- part[1] &= right.part[1];
- part[2] &= right.part[2];
- return *this;
- }
-
- inline flag96 operator |(const flag96 &right) const
- {
- return flag96(part[0] | right.part[0], part[1] | right.part[1],
- part[2] | right.part[2]);
- }
-
- inline flag96 & operator |=(const flag96 &right)
- {
- part[0] |= right.part[0];
- part[1] |= right.part[1];
- part[2] |= right.part[2];
- return *this;
- }
-
- inline flag96 operator ~() const
- {
- return flag96(~part[0], ~part[1], ~part[2]);
- }
-
- inline flag96 operator ^(const flag96 &right) const
- {
- return flag96(part[0] ^ right.part[0], part[1] ^ right.part[1],
- part[2] ^ right.part[2]);
- }
-
- inline flag96 & operator ^=(const flag96 &right)
- {
- part[0] ^= right.part[0];
- part[1] ^= right.part[1];
- part[2] ^= right.part[2];
- return *this;
- }
-
- inline operator bool() const
- {
- return (part[0] != 0 || part[1] != 0 || part[2] != 0);
- }
-
- inline bool operator !() const
- {
- return !this->operator bool();
- }
-
- inline uint32 & operator [](uint8 el)
- {
- return part[el];
- }
-
- inline const uint32 & operator [](uint8 el) const
- {
- return part[el];
- }
-};
-
-enum ComparisionType
-{
- COMP_TYPE_EQ = 0,
- COMP_TYPE_HIGH,
- COMP_TYPE_LOW,
- COMP_TYPE_HIGH_EQ,
- COMP_TYPE_LOW_EQ,
- COMP_TYPE_MAX
-};
-
-template <class T>
-bool CompareValues(ComparisionType type, T val1, T val2)
-{
- switch (type)
- {
- case COMP_TYPE_EQ:
- return val1 == val2;
- case COMP_TYPE_HIGH:
- return val1 > val2;
- case COMP_TYPE_LOW:
- return val1 < val2;
- case COMP_TYPE_HIGH_EQ:
- return val1 >= val2;
- case COMP_TYPE_LOW_EQ:
- return val1 <= val2;
- default:
- // incorrect parameter
- ASSERT(false);
- return false;
- }
-}
-
-#endif
diff --git a/src/server/worldserver/CMakeLists.txt b/src/server/worldserver/CMakeLists.txt
index a6c76977fe2..f513ba0857f 100644
--- a/src/server/worldserver/CMakeLists.txt
+++ b/src/server/worldserver/CMakeLists.txt
@@ -49,24 +49,23 @@ include_directories(
${CMAKE_SOURCE_DIR}/dep/SFMT
${CMAKE_SOURCE_DIR}/dep/cppformat
${CMAKE_SOURCE_DIR}/dep/process
- ${CMAKE_SOURCE_DIR}/src/server/collision
- ${CMAKE_SOURCE_DIR}/src/server/collision/Management
- ${CMAKE_SOURCE_DIR}/src/server/collision/Models
+ ${CMAKE_SOURCE_DIR}/src/server/database
+ ${CMAKE_SOURCE_DIR}/src/server/database/Database
+ ${CMAKE_SOURCE_DIR}/src/server/database/Logging
+ ${CMAKE_SOURCE_DIR}/src/server/database/Updater
+ ${CMAKE_SOURCE_DIR}/src/common/Collision
+ ${CMAKE_SOURCE_DIR}/src/common/Collision/Management
+ ${CMAKE_SOURCE_DIR}/src/common/Collision/Models
+ ${CMAKE_SOURCE_DIR}/src/common/Configuration
${CMAKE_SOURCE_DIR}/src/server/shared
- ${CMAKE_SOURCE_DIR}/src/server/shared/Configuration
${CMAKE_SOURCE_DIR}/src/server/shared/Cryptography
${CMAKE_SOURCE_DIR}/src/server/shared/Cryptography/Authentication
- ${CMAKE_SOURCE_DIR}/src/server/shared/Database
${CMAKE_SOURCE_DIR}/src/server/shared/DataStores
- ${CMAKE_SOURCE_DIR}/src/server/shared/Debugging
${CMAKE_SOURCE_DIR}/src/server/shared/Dynamic/LinkedReference
${CMAKE_SOURCE_DIR}/src/server/shared/Dynamic
- ${CMAKE_SOURCE_DIR}/src/server/shared/Logging
${CMAKE_SOURCE_DIR}/src/server/shared/Networking
${CMAKE_SOURCE_DIR}/src/server/shared/Packets
- ${CMAKE_SOURCE_DIR}/src/server/shared/Threading
- ${CMAKE_SOURCE_DIR}/src/server/shared/Updater
- ${CMAKE_SOURCE_DIR}/src/server/shared/Utilities
+ ${CMAKE_SOURCE_DIR}/src/server/shared/Service
${CMAKE_SOURCE_DIR}/src/server/game
${CMAKE_SOURCE_DIR}/src/server/game/Accounts
${CMAKE_SOURCE_DIR}/src/server/game/Achievements
@@ -135,6 +134,14 @@ include_directories(
${CMAKE_SOURCE_DIR}/src/server/game/World
${CMAKE_SOURCE_DIR}/src/server/authserver/Server
${CMAKE_SOURCE_DIR}/src/server/authserver/Realms
+ ${CMAKE_SOURCE_DIR}/src/common/
+ ${CMAKE_SOURCE_DIR}/src/common/Collision
+ ${CMAKE_SOURCE_DIR}/src/common/Collision/Management
+ ${CMAKE_SOURCE_DIR}/src/common/Collision/Models
+ ${CMAKE_SOURCE_DIR}/src/common/Debugging
+ ${CMAKE_SOURCE_DIR}/src/common/Utilities
+ ${CMAKE_SOURCE_DIR}/src/common/Threading
+ ${CMAKE_SOURCE_DIR}/src/common/Logging
${CMAKE_CURRENT_SOURCE_DIR}
${CMAKE_CURRENT_SOURCE_DIR}/CommandLine
${CMAKE_CURRENT_SOURCE_DIR}/RemoteAccess
@@ -165,9 +172,10 @@ set_target_properties(worldserver PROPERTIES LINK_FLAGS "${worldserver_LINK_FLAG
target_link_libraries(worldserver
game
+ common
shared
+ database
scripts
- collision
g3dlib
gsoap
Detour