Permalink
Find file
Fetching contributors…
Cannot retrieve contributors at this time
206 lines (178 sloc) 6.77 KB
/*
* Copyright (C) 2010 - 2016 Eluna Lua Engine <http://emudevs.com/>
* This program is free software licensed under GPL version 3
* Please see the included DOCS/LICENSE.md for more information
*/
#include "ElunaUtility.h"
#include "World.h"
#include "Object.h"
#include "Unit.h"
#include "GameObject.h"
#include "DBCStores.h"
uint32 ElunaUtil::GetCurrTime()
{
#ifndef TRINITY
return WorldTimer::getMSTime();
#else
return getMSTime();
#endif
}
uint32 ElunaUtil::GetTimeDiff(uint32 oldMSTime)
{
#ifndef TRINITY
return WorldTimer::getMSTimeDiff(oldMSTime, GetCurrTime());
#else
return GetMSTimeDiffToNow(oldMSTime);
#endif
}
ElunaUtil::ObjectGUIDCheck::ObjectGUIDCheck(ObjectGuid guid) : _guid(guid)
{
}
bool ElunaUtil::ObjectGUIDCheck::operator()(WorldObject* object)
{
return object->GET_GUID() == _guid;
}
ElunaUtil::ObjectDistanceOrderPred::ObjectDistanceOrderPred(WorldObject const* pRefObj, bool ascending) : m_refObj(pRefObj), m_ascending(ascending)
{
}
bool ElunaUtil::ObjectDistanceOrderPred::operator()(WorldObject const* pLeft, WorldObject const* pRight) const
{
return m_ascending ? m_refObj->GetDistanceOrder(pLeft, pRight) : !m_refObj->GetDistanceOrder(pLeft, pRight);
}
ElunaUtil::WorldObjectInRangeCheck::WorldObjectInRangeCheck(bool nearest, WorldObject const* obj, float range,
uint16 typeMask, uint32 entry, uint32 hostile, uint32 dead) :
i_obj(obj), i_obj_unit(nullptr), i_obj_fact(nullptr), i_hostile(hostile), i_entry(entry), i_range(range), i_typeMask(typeMask), i_dead(dead), i_nearest(nearest)
{
i_obj_unit = i_obj->ToUnit();
if (!i_obj_unit)
if (GameObject const* go = i_obj->ToGameObject())
i_obj_unit = go->GetOwner();
if (!i_obj_unit)
i_obj_fact = sFactionTemplateStore.LookupEntry(14);
}
WorldObject const& ElunaUtil::WorldObjectInRangeCheck::GetFocusObject() const
{
return *i_obj;
}
bool ElunaUtil::WorldObjectInRangeCheck::operator()(WorldObject* u)
{
if (i_typeMask && !u->isType(TypeMask(i_typeMask)))
return false;
if (i_entry && u->GetEntry() != i_entry)
return false;
if (i_obj->GET_GUID() == u->GET_GUID())
return false;
if (!i_obj->IsWithinDistInMap(u, i_range))
return false;
Unit const* target = u->ToUnit();
if (!target)
if (GameObject const* go = u->ToGameObject())
target = go->GetOwner();
if (target)
{
#ifdef CMANGOS
if (i_dead && (i_dead == 1) != target->isAlive())
return false;
#else
if (i_dead && (i_dead == 1) != target->IsAlive())
return false;
#endif
if (i_hostile)
{
if (!i_obj_unit)
{
if (i_obj_fact)
{
#ifdef TRINITY
if ((i_obj_fact->IsHostileTo(*target->GetFactionTemplateEntry())) != (i_hostile == 1))
return false;
#else
if ((i_obj_fact->IsHostileTo(*target->getFactionTemplateEntry())) != (i_hostile == 1))
return false;
#endif
}
else if (i_hostile == 1)
return false;
}
else if ((i_hostile == 1) != i_obj_unit->IsHostileTo(target))
return false;
}
}
if (i_nearest)
i_range = i_obj->GetDistance(u);
return true;
}
static char encoding_table[] = {'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H',
'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X',
'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f',
'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n',
'o', 'p', 'q', 'r', 's', 't', 'u', 'v',
'w', 'x', 'y', 'z', '0', '1', '2', '3',
'4', '5', '6', '7', '8', '9', '+', '/'};
static char decoding_table[256];
static int mod_table[] = {0, 2, 1};
static void build_decoding_table()
{
for (int i = 0; i < 64; i++)
decoding_table[(unsigned char)encoding_table[i]] = i;
}
void ElunaUtil::EncodeData(const unsigned char* data, size_t input_length, std::string& output)
{
size_t output_length = 4 * ((input_length + 2) / 3);
char* buffer = new char[output_length];
for (size_t i = 0, j = 0; i < input_length;)
{
uint32 octet_a = i < input_length ? (unsigned char)data[i++] : 0;
uint32 octet_b = i < input_length ? (unsigned char)data[i++] : 0;
uint32 octet_c = i < input_length ? (unsigned char)data[i++] : 0;
uint32 triple = (octet_a << 0x10) + (octet_b << 0x08) + octet_c;
buffer[j++] = encoding_table[(triple >> (3 * 6)) & 0x3F];
buffer[j++] = encoding_table[(triple >> (2 * 6)) & 0x3F];
buffer[j++] = encoding_table[(triple >> (1 * 6)) & 0x3F];
buffer[j++] = encoding_table[(triple >> (0 * 6)) & 0x3F];
}
for (int i = 0; i < mod_table[input_length % 3]; i++)
buffer[output_length - 1 - i] = '=';
output.assign(buffer, output_length); // Need length because `buffer` is not terminated!
delete[] buffer;
}
unsigned char* ElunaUtil::DecodeData(const char *data, size_t *output_length)
{
if (decoding_table[(unsigned char)'B'] == 0)
build_decoding_table();
size_t input_length = strlen(data);
if (input_length % 4 != 0)
return NULL;
// Make sure there's no invalid characters in the data.
for (size_t i = 0; i < input_length; ++i)
{
unsigned char byte = data[i];
if (byte == '=')
continue;
// Every invalid character (and 'A') will map to 0 (due to `calloc`).
if (decoding_table[byte] == 0 && byte != 'A')
return NULL;
}
*output_length = input_length / 4 * 3;
if (data[input_length - 1] == '=') (*output_length)--;
if (data[input_length - 2] == '=') (*output_length)--;
unsigned char *decoded_data = new unsigned char[*output_length];
if (!decoded_data)
return NULL;
for (size_t i = 0, j = 0; i < input_length;)
{
uint32 sextet_a = data[i] == '=' ? 0 & i++ : decoding_table[(unsigned char)data[i++]];
uint32 sextet_b = data[i] == '=' ? 0 & i++ : decoding_table[(unsigned char)data[i++]];
uint32 sextet_c = data[i] == '=' ? 0 & i++ : decoding_table[(unsigned char)data[i++]];
uint32 sextet_d = data[i] == '=' ? 0 & i++ : decoding_table[(unsigned char)data[i++]];
uint32 triple = (sextet_a << (3 * 6))
+ (sextet_b << (2 * 6))
+ (sextet_c << (1 * 6))
+ (sextet_d << (0 * 6));
if (j < *output_length) decoded_data[j++] = (triple >> (2 * 8)) & 0xFF;
if (j < *output_length) decoded_data[j++] = (triple >> (1 * 8)) & 0xFF;
if (j < *output_length) decoded_data[j++] = (triple >> (0 * 8)) & 0xFF;
}
return decoded_data;
}