gdle/Source/Util.cpp

897 lines
19 KiB
C++
Raw Permalink Normal View History

2018-03-29 17:01:57 -04:00
2019-07-07 20:56:15 +00:00
#include <StdAfx.h>
2018-03-29 17:01:57 -04:00
#include "TurbineFormats.h"
2019-02-04 16:54:20 -06:00
#include <random>
2018-03-29 17:01:57 -04:00
2019-07-07 20:56:15 +00:00
#if defined(_WIN32)
2018-03-29 17:01:57 -04:00
#pragma comment(lib, "psapi.lib")
2019-07-07 20:56:15 +00:00
#else
#include <sys/sysinfo.h>
#endif
2018-03-29 17:01:57 -04:00
namespace Random
{
2019-02-04 16:54:20 -06:00
static std::mt19937 _generator;
static std::uniform_real_distribution<double> _range_f(0.0f, 1.0f);
2018-03-29 17:01:57 -04:00
int m_iSeed;
void Init()
{
2019-02-04 16:54:20 -06:00
std::random_device rd;
_generator.seed(rd());
2018-03-29 17:01:57 -04:00
m_iSeed = (signed)((unsigned int)(time(0)*12345) << 2) - 144810491;
}
uint32_t GenRandom15()
{
m_iSeed = (m_iSeed * 214013) + 2531011;
uint32_t dwRandom15 = (unsigned)m_iSeed;
dwRandom15 >>= 16;
dwRandom15 &= 0x7FFF;
return dwRandom15;
}
uint32_t GenRandom32()
{
uint32_t dwRandom32 = 0;
dwRandom32 |= GenRandom15();
dwRandom32 <<= 15;
dwRandom32 |= GenRandom15();
dwRandom32 <<= 15;
dwRandom32 |= GenRandom15();
return dwRandom32;
}
uint32_t GenUInt(uint32_t min, uint32_t max)
{
if (max <= min)
return min;
2019-02-04 16:54:20 -06:00
std::uniform_int_distribution<uint32_t> range(min, max);
return range(_generator);
//unsigned int range = max - min;
//return (min + (GenRandom32() % (range + 1)));
2018-03-29 17:01:57 -04:00
}
int32_t GenInt(int32_t min, int32_t max)
{
if (max <= min)
return min;
2019-02-04 16:54:20 -06:00
std::uniform_int_distribution<int32_t> range(min, max);
return range(_generator);
//unsigned int range = (unsigned)(max - min);
//return (min + (int)(GenRandom32() % (range + 1)));
}
double GenFloat()
{
return _range_f(_generator);
2018-03-29 17:01:57 -04:00
}
double GenFloat(double min, double max)
{
if (max <= min)
return min;
double range = max - min;
2019-02-04 16:54:20 -06:00
//double value = min + (range * ((double)GenRandom32() / 0xFFFFFFFF));
double value = min + (range * _range_f(_generator));
2018-03-29 17:01:57 -04:00
return value;
}
float GenFloat(float min, float max)
{
if (max <= min)
return min;
double range = max - min;
2019-02-04 16:54:20 -06:00
//double value = min + (range * ((double)GenRandom32() / 0xFFFFFFFF));
double value = min + (range * _range_f(_generator));
2018-03-29 17:01:57 -04:00
return (float)value;
}
float RollDice(float min, float max)
{
return GenFloat(min, max);
}
2018-03-29 17:01:57 -04:00
}
2019-07-07 20:56:15 +00:00
//void EnumerateFolderFilePaths(std::list<std::string> &results, const char *basePath, const char *fileMask, bool bSubFolders)
//{
// std::string basePathStr(basePath);
// basePathStr += "\\";
//
// WIN32_FIND_DATA data;
// HANDLE hFind = FindFirstFile((basePathStr + fileMask).c_str(), &data);
//
// if (hFind != INVALID_HANDLE_VALUE)
// {
// do
// {
// if ((data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0)
// {
// continue;
// }
//
// results.push_back(basePathStr + data.cFileName);
//
// } while (FindNextFile(hFind, &data));
//
// CloseHandle(INVALID_HANDLE_VALUE);
// }
//
// if (bSubFolders)
// {
// hFind = FindFirstFile((basePathStr + "*").c_str(), &data);
// if (hFind != INVALID_HANDLE_VALUE)
// {
// do
// {
// if ((data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0)
// {
// if (!strcmp(data.cFileName, ".") || !strcmp(data.cFileName, ".."))
// continue;
//
// std::string subFolderStr;
// subFolderStr = basePathStr + data.cFileName;
// EnumerateFolderFilePaths(results, subFolderStr.c_str(), fileMask, true);
// continue;
// }
// } while (FindNextFile(hFind, &data));
// CloseHandle(INVALID_HANDLE_VALUE);
// }
// }
//}
2018-03-29 17:01:57 -04:00
char NibbleToChar(int n)
{
if (n < 10)
return '0' + n;
else
return 'a' + (n - 10);
}
char NibbleToCharUCase(int n)
{
if (n < 10)
return '0' + n;
else
return 'A' + (n - 10);
}
char *DataToHexString(const void *input, unsigned int inputlen, char *output)
{
uint8_t *data = (uint8_t *)input;
for (unsigned int i = 0; i < inputlen; i++)
{
output[(i << 1) + 0] = NibbleToChar((data[i] & 0xF0) >> 4);
output[(i << 1) + 1] = NibbleToChar((data[i] & 0x0F) >> 0);
}
output[inputlen << 1] = '\0';
return output;
}
2019-07-07 20:56:15 +00:00
bool LoadDataFromFile(const char *filepath, BYTE **data, uint32_t *length)
2018-03-29 17:01:57 -04:00
{
*data = NULL;
*length = 0;
FILE *fp = fopen(filepath, "rb");
if (fp)
{
fseek(fp, 0, SEEK_END);
long _fileSize = ftell(fp);
fseek(fp, 0, SEEK_SET);
if (_fileSize < 0)
_fileSize = 0;
2019-07-07 20:56:15 +00:00
uint32_t fileSize = (uint32_t)_fileSize;
2018-03-29 17:01:57 -04:00
BYTE *fileData = new BYTE[fileSize];
fread(fileData, fileSize, 1, fp);
fclose(fp);
*data = fileData;
*length = fileSize;
return true;
}
return false;
}
2019-07-07 20:56:15 +00:00
bool LoadDataFromCompressed_(BYTE *input_data, uint32_t input_length, BYTE **data, uint32_t *length, uint32_t magic1, uint32_t magic2)
2018-03-29 17:01:57 -04:00
{
*data = NULL;
*length = 0;
2019-07-07 20:56:15 +00:00
uint32_t packing = magic1;
for (uint32_t i = 0; i < (input_length >> 2); i++) {
((uint32_t *)input_data)[i] += ((i + 1) * packing);
2018-03-29 17:01:57 -04:00
packing ^= magic2;
}
2019-07-07 20:56:15 +00:00
uint32_t decompressed_size = *((uint32_t *)input_data);
BYTE *compressed_buffer = input_data + sizeof(uint32_t);
uint32_t compressed_size = input_length - sizeof(uint32_t);
2018-03-29 17:01:57 -04:00
*data = new BYTE[decompressed_size];
*length = decompressed_size;
bool success = true;
2019-07-07 20:56:15 +00:00
uLongf ulf = decompressed_size;
if (Z_OK != uncompress(*data, &ulf, compressed_buffer, compressed_size))
2018-03-29 17:01:57 -04:00
{
delete[](*data);
*data = NULL;
*length = 0;
success = false;
}
2019-07-07 20:56:15 +00:00
*length = (uint32_t)ulf;
2018-03-29 17:01:57 -04:00
return success;
}
2019-07-07 20:56:15 +00:00
bool LoadDataFromCompressedFile(const char *filepath, BYTE **data, uint32_t *length, uint32_t magic1, uint32_t magic2)
2018-03-29 17:01:57 -04:00
{
*data = NULL;
*length = 0;
BYTE *input_data = NULL;
2019-07-07 20:56:15 +00:00
uint32_t input_length = 0;
2018-03-29 17:01:57 -04:00
if (LoadDataFromFile(filepath, &input_data, &input_length))
{
bool success = LoadDataFromCompressed_(input_data, input_length, data, length, magic1, magic2);
delete[] input_data;
return success;
}
return false;
}
long FindNeedle(void *haystack, unsigned int haystacklength, void *needle, unsigned int needlelength)
{
if (haystacklength < needlelength)
return -1;
if (!needlelength)
return -1;
BYTE *dataPos = (BYTE *)haystack;
BYTE *dataEnd = (dataPos + haystacklength - needlelength);
bool found = false;
while (dataPos <= dataEnd)
{
if (!memcmp(dataPos, needle, needlelength))
{
found = true;
break;
}
dataPos++;
}
if (!found)
return -1;
return (dataPos - (BYTE *)haystack);
}
// returns a string of "Xmo, Xd, Xh, Xm, Xs"
std::string TimeToString(int seconds)
{
int mo = seconds / 2629800; // seconds in a month
int leftover = seconds % 2629800;
int d = leftover / 86400; // seconds in a day
leftover %= 86400;
int h = leftover / 3600; // seconds in an hour
leftover %= 3600;
int m = leftover / 60; // seconds in a minute
leftover %= 60;
int s = leftover;
std::string out = "";
if (mo)
out += csprintf("%dmo ", mo);
if (d)
out += csprintf("%dd ", d);
if (h)
out += csprintf("%dh ", h);
if (m)
out += csprintf("%dm ", m);
out += csprintf("%ds", s);
return out;
}
2018-03-29 17:01:57 -04:00
bool ReplaceString(std::string& str, const std::string& from, const std::string& to) {
size_t start_pos = str.find(from);
if (start_pos == std::string::npos)
return false;
str.replace(start_pos, from.length(), to);
return true;
}
std::string ReplaceInString(std::string subject, const std::string& search,
const std::string& replace) {
size_t pos = 0;
while ((pos = subject.find(search, pos)) != std::string::npos) {
subject.replace(pos, search.length(), replace);
pos += replace.length();
}
return subject;
}
2018-03-29 17:01:57 -04:00
static char szReadBuffer[1024];
static char szWriteBuffer[600];
char* csprintf(const char *format, ...)
{
szReadBuffer[0] = 0;
va_list args;
va_start(args, format);
2019-07-07 20:56:15 +00:00
vsnprintf(szReadBuffer, 1024, format, args);
2018-03-29 17:01:57 -04:00
va_end(args);
szReadBuffer[1023] = '\0';
return szReadBuffer;
}
char *timestamp()
{
static char result[64];
tm *beef;
time_t cake;
time(&cake);
beef = localtime(&cake);
if (beef)
sprintf(result, "%.2d:%.2d:%.2d", beef->tm_hour, beef->tm_min, beef->tm_sec);
else
result[0] = 0;
return result;
}
char *timestampDateString(time_t ts)
{
static char result[64];
tm *beef;
time_t cake = ts;
beef = localtime(&cake);
if (beef)
sprintf(result, "%d/%02d/%d %02d:%02d:%02d", beef->tm_mon + 1, beef->tm_mday, beef->tm_year + 1900, beef->tm_hour, beef->tm_min, beef->tm_sec);
else
result[0] = 0;
return result;
}
char *timestampDateStringForFileName(time_t ts)
{
static char result[64];
tm *beef;
time_t cake = ts;
beef = localtime(&cake);
if (beef)
sprintf(result, "%04d_%02d_%02d__%02d_%02d_%02d", beef->tm_year + 1900, beef->tm_mon + 1, beef->tm_mday, beef->tm_hour, beef->tm_min, beef->tm_sec);
else
result[0] = 0;
return result;
}
unsigned long ResolveIPFromHost(const char *host)
{
ULONG ipaddr;
// Check if it's in IP format.
ipaddr = ::inet_addr(host);
if (ipaddr && ipaddr != INADDR_NONE)
return (unsigned long)ipaddr;
// Try to resolve an IP address.
2019-07-07 20:56:15 +00:00
hostent *lphost;
2018-03-29 17:01:57 -04:00
lphost = gethostbyname(host);
if (lphost != NULL)
{
2019-07-07 20:56:15 +00:00
ipaddr = ((in_addr*)lphost->h_addr)->s_addr;
2018-03-29 17:01:57 -04:00
if (ipaddr && ipaddr != INADDR_NONE)
return (unsigned long)ipaddr;
}
return 0;
}
unsigned long GetLocalIP()
{
char hostname[256];
gethostname(hostname, 256);
2019-07-07 20:56:15 +00:00
uint32_t hostaddr = *((uint32_t *)gethostbyname(hostname)->h_addr);
2018-03-29 17:01:57 -04:00
return *(unsigned long *)gethostbyname(hostname)->h_addr;
}
std::string GetLocalIPString()
{
unsigned long localIP = GetLocalIP();
return inet_ntoa(*(in_addr *)&localIP);
}
std::string DebugBytesToString(void *_data, unsigned int len)
{
BYTE *data = (BYTE *)_data;
std::string strBytes;
for (unsigned int i = 0; i < len; i++)
{
char temp[3];
sprintf(temp, "%02X", data[i]);
strBytes += temp;
if (!((i + 1) % 16))
strBytes += "\n";
else
strBytes += " ";
}
if (len % 16)
{
strBytes += "\n";
}
return strBytes;
}
2019-07-07 20:56:15 +00:00
//void MsgBox(UINT type, const char *format, ...)
//{
// szWriteBuffer[0] = 0;
//
// va_list args;
// va_start(args, format);
// _vsnprintf(szWriteBuffer, 1024, format, args);
// va_end(args);
//
// HWND hWnd = g_pGlobals ? g_pGlobals->GetWindowHandle() : NULL;
//
// MessageBox(hWnd, szWriteBuffer, "GDL", MB_OK | type);
//}
2018-03-29 17:01:57 -04:00
2019-07-07 20:56:15 +00:00
//void MsgBox(const char *format, ...)
//{
// szWriteBuffer[0] = 0;
//
// va_list args;
// va_start(args, format);
// _vsnprintf(szWriteBuffer, 1024, format, args);
// va_end(args);
//
// MessageBox(NULL, szWriteBuffer, "GDL", MB_OK);
//}
//void MsgBoxError(uint32_t dwError, const char* event)
//{
// LPVOID lpMsgBuf;
// if (!FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
// FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
// NULL,
// GetLastError(),
// MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
// (LPTSTR)&lpMsgBuf,
// 0, NULL))
// {
// MsgBox(MB_ICONHAND, "Unknown error #%lu %s", dwError, event);
// return;
// }
//
// MsgBox(MB_ICONHAND, "Error #%lu %s:\r\n%s", dwError, event, lpMsgBuf);
//
// LocalFree(lpMsgBuf);
//}
//#define REGLOC HKEY_LOCAL_MACHINE, "Software\\GDL"
//BOOL SaveConfigKey(const char* Key, uint32_t value)
//{
// BOOL bReturn = FALSE;
// HKEY hKey;
// if (RegCreateKeyEx(REGLOC, NULL, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hKey, NULL) == ERROR_SUCCESS)
// {
// if (SUCCEEDED(RegSetValueEx(hKey, Key, NULL, REG_uint32_t, (BYTE *)&value, sizeof(uint32_t))))
// bReturn = TRUE;
// RegCloseKey(hKey);
// }
// return bReturn;
//}
//BOOL SaveConfigKey(const char* Key, const char* value)
//{
// BOOL bReturn = FALSE;
// HKEY hKey;
// if (RegCreateKeyEx(REGLOC, NULL, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hKey, NULL) == ERROR_SUCCESS)
// {
// if (SUCCEEDED(RegSetValueEx(hKey, Key, NULL, REG_SZ, (BYTE*)value, (uint32_t)strlen(value) + 1)))
// bReturn = TRUE;
// RegCloseKey(hKey);
// }
// return bReturn;
//}
//BOOL ReadConfigKey(const char* Key, uint32_t* value)
//{
// uint32_t type = REG_uint32_t;
// uint32_t size = sizeof(uint32_t);
// BOOL bReturn = FALSE;
// HKEY hKey;
// if (RegOpenKeyEx(REGLOC, NULL, KEY_QUERY_VALUE, &hKey) == ERROR_SUCCESS)
// {
// if (!RegQueryValueEx(hKey, Key, NULL, &type, (BYTE*)value, &size))
// bReturn = TRUE;
// RegCloseKey(hKey);
// }
// return bReturn;
//}
//BOOL ReadConfigKey(const char* Key, char* value, uint32_t size)
//{
// uint32_t type = REG_SZ;
// BOOL bReturn = FALSE;
// HKEY hKey;
// if (RegOpenKeyEx(REGLOC, NULL, KEY_QUERY_VALUE, &hKey) == ERROR_SUCCESS)
// {
// if (!RegQueryValueEx(hKey, Key, NULL, &type, (BYTE*)value, &size))
// bReturn = TRUE;
// RegCloseKey(hKey);
// }
// return bReturn;
//}
2018-03-29 17:01:57 -04:00
bool FileExists(const char *filePath)
{
2019-07-07 20:56:15 +00:00
if (fs::exists(filePath))
return !fs::is_directory(filePath);
return false;
//uint32_t dwAttrib = GetFileAttributes(filePath);
//return (dwAttrib != INVALID_FILE_ATTRIBUTES && !(dwAttrib & FILE_ATTRIBUTE_DIRECTORY));
2018-03-29 17:01:57 -04:00
}
void strtrim(char *szText)
{
//how many left spaces are leading?
int leading = 0;
while (szText[leading] == ' ')
leading++;
if (leading) { //shift left
int i = leading;
while (1)
{
szText[i - leading] = szText[i];
if (szText[i] == 0)
break;
i++;
}
}
int pos = (int)strlen(szText) - 1; //remove trailing spaces
while ((pos >= 0) && szText[pos] == ' ')
szText[pos--] = 0;
}
BOOL strmask(const char* szTest, const char* szMask)
{
//We need to someday create a function for validating a string mask.
return FALSE;
}
long fsize(FILE* fileptr)
{
long lOld, lSize;
lOld = ftell(fileptr);
fseek(fileptr, 0, SEEK_END);
lSize = ftell(fileptr);
fseek(fileptr, lOld, SEEK_SET);
return lSize;
}
float NorthSouth(char *szCoord)
{
2019-07-07 20:56:15 +00:00
std::string coords = szCoord;
std::transform(coords.begin(), coords.end(), coords.begin(), ::tolower);
coords.erase(coords.begin(), std::find_if(coords.begin(), coords.end(), [](int c) { return !std::isspace(c); }));
coords.erase(std::find_if(coords.rbegin(), coords.rend(), [](int c) { return !std::isspace(c); }).base(), coords.end());
2018-03-29 17:01:57 -04:00
2019-07-07 20:56:15 +00:00
float dir = 1.0f;
2018-03-29 17:01:57 -04:00
2019-07-07 20:56:15 +00:00
int len = coords.length();
if (len < 1)
return 0;
2018-03-29 17:01:57 -04:00
2019-07-07 20:56:15 +00:00
size_t pos = coords.find(',');
if (pos == std::string::npos) // assume at the end
2019-08-01 03:32:09 +00:00
pos = len;
2019-07-07 20:56:15 +00:00
pos--;
char NS = coords[pos];
if (NS == 's')
dir = -1.0f;
2019-08-01 03:32:09 +00:00
coords[pos] = 0;
2019-07-07 20:56:15 +00:00
float coord = 0.0f;
2019-08-01 03:32:09 +00:00
sscanf(coords.data(), "%f", &coord);
2019-07-07 20:56:15 +00:00
return coord * dir;
2018-03-29 17:01:57 -04:00
}
float EastWest(char *szCoord)
{
2019-07-07 20:56:15 +00:00
std::string coords = szCoord;
std::transform(coords.begin(), coords.end(), coords.begin(), ::tolower);
coords.erase(coords.begin(), std::find_if(coords.begin(), coords.end(), [](int c) { return !std::isspace(c); }));
coords.erase(std::find_if(coords.rbegin(), coords.rend(), [](int c) { return !std::isspace(c); }).base(), coords.end());
2018-03-29 17:01:57 -04:00
2019-07-07 20:56:15 +00:00
float dir = 1.0f;
int len = coords.length();
if (len < 1)
return 0;
size_t pos = coords.find(',');
if (pos == std::string::npos) // assume at the end
2019-08-01 03:32:09 +00:00
pos = len;
2019-07-07 20:56:15 +00:00
pos--;
char EW = coords[pos];
if (EW == 'w')
dir = -1.0f;
2019-08-01 03:32:09 +00:00
coords[pos] = 0;
2019-07-07 20:56:15 +00:00
float coord = 0.0f;
2019-08-01 03:32:09 +00:00
sscanf(coords.data(), "%f", &coord);
2019-07-07 20:56:15 +00:00
return coord * dir;
2018-03-29 17:01:57 -04:00
}
2019-07-07 20:56:15 +00:00
uint32_t GetCellFromBase(uint32_t BaseX, uint32_t BaseY)
2018-03-29 17:01:57 -04:00
{
BYTE blockx = (BYTE)(BaseX >> 3);
BYTE blocky = (BYTE)(BaseY >> 3);
BYTE cellx = (BYTE)(BaseX & 7);
BYTE celly = (BYTE)(BaseY & 7);
WORD block = (blockx << 8) | (blocky);
WORD cell = (cellx << 3) | (celly);
2019-07-07 20:56:15 +00:00
uint32_t dwCell = (block << 16) | (cell + 1);
2018-03-29 17:01:57 -04:00
return dwCell;
}
bool GetLocation(double NS, double EW, Position &pos)
{
NS -= 0.5f;
EW -= 0.5f;
NS *= 10.0f;
EW *= 10.0f;
2019-07-07 20:56:15 +00:00
uint32_t basex = (uint32_t)(EW + 0x400);
uint32_t basey = (uint32_t)(NS + 0x400);
2018-03-29 17:01:57 -04:00
2019-08-01 03:32:09 +00:00
if (int32_t(basex) < 0 || int32_t(basey) < 0 || basex >= 0x7F8 || basey >= 0x7F8)
2018-03-29 17:01:57 -04:00
{
//Out of bounds.
pos = Position();
return false;
}
2019-07-07 20:56:15 +00:00
uint32_t dwCell = GetCellFromBase(basex, basey);
2018-03-29 17:01:57 -04:00
float xOffset = ((basex & 7) * 24.0f) + 12;
float yOffset = ((basey & 7) * 24.0f) + 12;
pos = Position(dwCell, Vector(xOffset, yOffset, CalcSurfaceZ(dwCell, xOffset, yOffset)));
return true;
}
// Water blocks are not passable!
BOOL IsWaterBlock(BlockData *pBlock)
{
for (unsigned int x = 0; x < 9; x++) {
for (unsigned int y = 0; y < 9; y++) {
if ((pBlock->wSurface[x][y] & 0x50) != 0x50)
return FALSE;
}
}
return TRUE;
}
//
2019-07-07 20:56:15 +00:00
BOOL IsWaterBlock(uint32_t dwCell)
2018-03-29 17:01:57 -04:00
{
dwCell &= 0xFFFF0000;
dwCell |= 0x0000FFFF;
TURBINEFILE *pFile = g_pCell->GetFile(dwCell);
if (!pFile)
return FALSE;
BOOL bResult = IsWaterBlock((BlockData*)pFile->GetData());
delete pFile;
return bResult;
}
BOOL HasObjectBlock(BlockData *pBlock)
{
return ((pBlock->bObject) ? TRUE : FALSE);
}
2019-07-07 20:56:15 +00:00
BOOL HasObjectBlock(uint32_t dwCell)
2018-03-29 17:01:57 -04:00
{
dwCell &= 0xFFFF0000;
dwCell |= 0x0000FFFF;
TURBINEFILE *pFile = g_pCell->GetFile(dwCell);
if (!pFile)
return FALSE;
BOOL bResult = HasObjectBlock((BlockData*)pFile->GetData());
delete pFile;
return bResult;
}
2019-07-07 20:56:15 +00:00
float CalcSurfaceZ(uint32_t dwCell, float xOffset, float yOffset, bool bUseLCell)
2018-03-29 17:01:57 -04:00
{
TURBINEFILE *pFile = g_pCell->GetFile((dwCell & 0xFFFF0000) | 0xFFFF);
if (!pFile)
return 0;
WORD cell = CELL_WORD(dwCell);
int minix = (cell >> 3) & 7;
int miniy = (cell >> 0) & 7;
if (bUseLCell)
{
xOffset -= (24 * minix);
yOffset -= (24 * miniy);
}
BlockData *pBlock = (BlockData*)pFile->GetData();
Vector P1(0, 24, LandDefs::Land_Height_Table[pBlock->bHeight[minix][miniy + 1]] + 0.005f);
2018-03-29 17:01:57 -04:00
Vector P2;
Vector P3(24, 0, LandDefs::Land_Height_Table[pBlock->bHeight[minix + 1][miniy]] + 0.005f);
2018-03-29 17:01:57 -04:00
2020-03-16 18:15:40 +00:00
if ((xOffset + yOffset) < 24.0f)
P2 = Vector(0, 0, LandDefs::Land_Height_Table[pBlock->bHeight[minix][miniy]] + 0.005f);
2018-03-29 17:01:57 -04:00
else
P2 = Vector(24, 24, LandDefs::Land_Height_Table[pBlock->bHeight[minix + 1][miniy + 1]] + 0.005f);
2018-03-29 17:01:57 -04:00
delete pFile;
return FindVectorZ(P1, P2, P3, xOffset, yOffset);
}
2019-07-07 20:56:15 +00:00
uint64_t GetProcessMemoryUsage()
2018-03-29 17:01:57 -04:00
{
2019-07-07 20:56:15 +00:00
#if defined(_WIN32)
2018-03-29 17:01:57 -04:00
PROCESS_MEMORY_COUNTERS_EX procMem;
memset(&procMem, 0, sizeof(procMem));
GetProcessMemoryInfo(GetCurrentProcess(), (PPROCESS_MEMORY_COUNTERS)&procMem, sizeof(procMem));
return procMem.PrivateUsage;
2019-07-07 20:56:15 +00:00
#elif defined(__linux__) || defined(__linux) || defined(linux) || defined(__gnu_linux__)
uint64_t result = 0;
FILE *fp = NULL;
2020-08-08 04:48:54 +00:00
if ((fp = fopen("/proc/self/statm", "r")))
2019-07-07 20:56:15 +00:00
{
2020-08-08 04:48:54 +00:00
fscanf(fp, "%lu", &result);
2019-07-07 20:56:15 +00:00
fclose(fp);
}
return result * (uint64_t)sysconf(_SC_PAGESIZE);
#else
return 0;
#endif
}
uint64_t GetFreeMemory()
{
#if defined(_WIN32)
2018-03-29 17:01:57 -04:00
MEMORYSTATUSEX status;
status.dwLength = sizeof(status);
GlobalMemoryStatusEx(&status);
return status.ullAvailPhys;
2019-07-07 20:56:15 +00:00
#elif defined(__linux__) || defined(__linux) || defined(linux) || defined(__gnu_linux__)
struct sysinfo si = { 0 };
sysinfo(&si);
return si.freeram;
#else
return 0;
#endif
2018-03-29 17:01:57 -04:00
}
2019-07-07 20:56:15 +00:00
uint64_t GetTotalMemory()
2018-03-29 17:01:57 -04:00
{
2019-07-07 20:56:15 +00:00
#if defined(_WIN32)
2018-03-29 17:01:57 -04:00
MEMORYSTATUSEX status;
status.dwLength = sizeof(status);
GlobalMemoryStatusEx(&status);
return status.ullTotalPhys;
2019-07-07 20:56:15 +00:00
#elif defined(__linux__) || defined(__linux) || defined(linux) || defined(__gnu_linux__)
struct sysinfo si = { 0 };
sysinfo(&si);
return si.totalram;
#else
return 0;
#endif
}
// strictness 1 = chat, strictness 2 = player names, titles, allegiance names
bool containsBadCharacters(std::string input, int strictness)
{
std::string goodChars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'- ";
if (strictness == 1)
{
2019-07-07 20:56:15 +00:00
goodChars += "!\"<EFBFBD>$%^&*()_-+={}[]:;<>,.?/@'~#`<60>|\\";
}
for (auto c : input)
{
if (goodChars.find(c) != goodChars.npos)
{
continue;
}
else
return true;
}
return false;
2019-07-07 20:56:15 +00:00
}
float GetRatingMod(int ratingAdj)
{
if (ratingAdj > 0)
{
return (100 + (float)ratingAdj) / 100;
}
else if (ratingAdj < 0)
{
return 100 / (100 + (float)ratingAdj);
}
return 1.0;
}