/** Copyright (C) 2005-2011 MaNGOS <http://getmangos.com/>* Copyright (C) 2009-2011 MaNGOSZero <https://github.com/mangos/zero>* Copyright (C) 2011-2016 Nostalrius <https://nostalrius.org>* Copyright (C) 2016-2017 Elysium Project <https://github.com/elysium-project>** This program is free software; you can redistribute it and/or modify* it under the terms of the GNU General Public License as published by* the Free Software Foundation; either version 2 of the License, or* (at your option) any later version.** This program is distributed in the hope that it will be useful,* but WITHOUT ANY WARRANTY; without even the implied warranty of* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the* GNU General Public License for more details.** You should have received a copy of the GNU General Public License* along with this program; if not, write to the Free Software* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA*/#include "Util.h"#include "Timer.h"#include "utf8cpp/utf8.h"#include "mersennetwister/MersenneTwister.h"#include <ace/TSS_T.h>#include <ace/OS_NS_arpa_inet.h>typedef ACE_TSS<MTRand> MTRandTSS;static MTRandTSS mtRand;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 thingsif (posold != posnew)m_storage.push_back(posold);break;}++posnew;}}static ACE_Time_Value g_SystemTickTime = ACE_OS::gettimeofday();uint32 WorldTimer::m_iTime = 0;uint32 WorldTimer::m_iPrevTime = 0;uint32 WorldTimer::tickTime() { return m_iTime; }uint32 WorldTimer::tickPrevTime() { return m_iPrevTime; }uint32 WorldTimer::tick(){//save previous world tick timem_iPrevTime = m_iTime;//get the new one and don't forget to persist current system time in m_SystemTickTimem_iTime = WorldTimer::getMSTime_internal(true);//return tick diffreturn getMSTimeDiff(m_iPrevTime, m_iTime);}uint32 WorldTimer::getMSTime(){return getMSTime_internal();}uint32 WorldTimer::getMSTime_internal(bool savetime /*= false*/){//get current timeconst ACE_Time_Value currTime = ACE_OS::gettimeofday();//calculate time diff between two world ticks//special case: curr_time < old_time - we suppose that our time has not ticked at all//this should be constant value otherwise it is possible that our time can start ticking backwards until next world tick!!!uint64 diff = 0;(currTime - g_SystemTickTime).msec(diff);//lets calculate current world timeuint32 iRes = uint32(diff % UI64LIT(0x00000000FFFFFFFF));return iRes;}//////////////////////////////////////////////////////////////////////////int32 irand (int32 min, int32 max){return int32 (mtRand->randInt (max - min)) + min;}uint32 urand (uint32 min, uint32 max){return mtRand->randInt (max - min) + min;}float frand (float min, float max){return mtRand->randExc (max - min) + min;}int32 rand32 (){return mtRand->randInt ();}double rand_norm(void){return mtRand->randExc ();}float rand_norm_f(void){return (float)mtRand->randExc ();}double rand_chance (void){return mtRand->randExc (100.0);}float rand_chance_f(void){return (float)mtRand->randExc (100.0);}Milliseconds randtime(Milliseconds const& min, Milliseconds const& max){long long diff = max.count() - min.count();MANGOS_ASSERT(diff >= 0);MANGOS_ASSERT(diff <= (uint32)-1);return min + Milliseconds(urand(0, diff));}Tokens StrSplit(const std::string &src, const std::string &sep){Tokens r;std::string s;for (std::string::const_iterator i = src.begin(); i != src.end(); i++){if (sep.find(*i) != std::string::npos){if (s.length()) r.push_back(s);s = "";}else{s += *i;}}if (s.length()) r.push_back(s);return r;}uint32 GetUInt32ValueFromArray(Tokens const& data, uint16 index){if(index >= data.size())return 0;return (uint32)atoi(data[index].c_str());}float GetFloatValueFromArray(Tokens const& data, uint16 index){float result;uint32 temp = GetUInt32ValueFromArray(data,index);memcpy(&result, &temp, sizeof(result));return result;}void stripLineInvisibleChars(std::string &str){static std::string invChars = " \t7円\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());}std::string secsToTimeString(time_t timeInSecs, bool shortText, bool hoursOnly){time_t secs = timeInSecs % MINUTE;time_t minutes = timeInSecs % HOUR / MINUTE;time_t hours = timeInSecs % DAY / HOUR;time_t days = timeInSecs / DAY;std::ostringstream ss;if(days){ss << days;if (shortText)ss << "d";else if (days == 1)ss << " Day ";elsess << " Days ";}if(hours || hoursOnly){ss << hours;if (shortText)ss << "h";else if (hours <= 1)ss << " Hour ";elsess << " Hours ";}if(!hoursOnly){if(minutes){ss << minutes;if (shortText)ss << "m";else if (minutes == 1)ss << " Minute ";elsess << " Minutes ";}if (secs || (!days && !hours && !minutes)){ss << secs;if (shortText)ss << "s";else if (secs <= 1)ss << " Second.";elsess << " Seconds.";}}return ss.str();}uint32 TimeStringToSecs(const std::string& timestring){uint32 secs = 0;uint32 buffer = 0;uint32 multiplier = 0;for(std::string::const_iterator itr = timestring.begin(); itr != timestring.end(); itr++ ){if(isdigit(*itr)){buffer*=10;buffer+= (*itr)-'0';}else{switch(*itr){case 'd': multiplier = DAY; break;case 'h': multiplier = HOUR; break;case 'm': multiplier = MINUTE; break;case 's': multiplier = 1; break;default : return 0; //bad format}buffer*=multiplier;secs+=buffer;buffer=0;}}return secs;}std::string TimeToTimestampStr(time_t t){tm* aTm = localtime(&t);// YYYY year// MM month (2 digits 01-12)// DD day (2 digits 01-31)// HH hour (2 digits 00-23)// MM minutes (2 digits 00-59)// SS seconds (2 digits 00-59)char buf[20];snprintf(buf,20,"%04d-%02d-%02d_%02d-%02d-%02d",aTm->tm_year+1900,aTm->tm_mon+1,aTm->tm_mday,aTm->tm_hour,aTm->tm_min,aTm->tm_sec);return std::string(buf);}/// Check if the string is a valid ip address representationbool 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 ACE_OS::inet_addr(ipaddress) != INADDR_NONE;}/// create PID fileuint32 CreatePIDFile(const std::string& filename){FILE * pid_file = fopen (filename.c_str(), "w" );if (pid_file == NULL)return 0;#ifdef WIN32DWORD pid = GetCurrentProcessId();#elsepid_t pid = getpid();#endiffprintf(pid_file, "%d", pid );fclose(pid_file);return (uint32)pid;}size_t utf8length(std::string& utf8str){try{return utf8::distance(utf8str.c_str(),utf8str.c_str()+utf8str.size());}catch(std::exception){utf8str = "";return 0;}}void utf8truncate(std::string& utf8str,size_t len){try{size_t wlen = utf8::distance(utf8str.c_str(),utf8str.c_str()+utf8str.size());if(wlen <= len)return;std::wstring wstr;wstr.resize(wlen);utf8::utf8to16(utf8str.c_str(),utf8str.c_str()+utf8str.size(),&wstr[0]);wstr.resize(len);char* oend = utf8::utf16to8(wstr.c_str(),wstr.c_str()+wstr.size(),&utf8str[0]);utf8str.resize(oend-(&utf8str[0])); // remove unused tail}catch(std::exception){utf8str = "";}}bool Utf8toWStr(char const* utf8str, size_t csize, wchar_t* wstr, size_t& wsize){try{size_t len = utf8::distance(utf8str,utf8str+csize);if(len > wsize){if(wsize > 0)wstr[0] = L'0円';wsize = 0;return false;}wsize = len;utf8::utf8to16(utf8str,utf8str+csize,wstr);wstr[len] = L'0円';}catch(std::exception){if(wsize > 0)wstr[0] = L'0円';wsize = 0;return false;}return true;}bool Utf8toWStr(const std::string& utf8str, std::wstring& wstr){try{size_t len = utf8::distance(utf8str.c_str(),utf8str.c_str()+utf8str.size());wstr.resize(len);if (len)utf8::utf8to16(utf8str.c_str(),utf8str.c_str()+utf8str.size(),&wstr[0]);}catch(std::exception){wstr = L"";return false;}return true;}bool WStrToUtf8(wchar_t* wstr, size_t size, std::string& utf8str){try{std::string utf8str2;utf8str2.resize(size*4); // allocate for most long casechar* oend = utf8::utf16to8(wstr,wstr+size,&utf8str2[0]);utf8str2.resize(oend-(&utf8str2[0])); // remove unused tailutf8str = utf8str2;}catch(std::exception){utf8str = "";return false;}return true;}bool WStrToUtf8(std::wstring wstr, std::string& utf8str){try{std::string utf8str2;utf8str2.resize(wstr.size()*4); // allocate for most long casechar* oend = utf8::utf16to8(wstr.c_str(),wstr.c_str()+wstr.size(),&utf8str2[0]);utf8str2.resize(oend-(&utf8str2[0])); // remove unused tailutf8str = utf8str2;}catch(std::exception){utf8str = "";return false;}return true;}typedef wchar_t const* const* wstrlist;bool utf8ToConsole(const std::string& utf8str, std::string& conStr){#if PLATFORM == PLATFORM_WINDOWSstd::wstring wstr;if(!Utf8toWStr(utf8str,wstr))return false;conStr.resize(wstr.size());CharToOemBuffW(&wstr[0],&conStr[0],wstr.size());#else// not implemented yetconStr = utf8str;#endifreturn true;}bool consoleToUtf8(const std::string& conStr,std::string& utf8str){#if PLATFORM == PLATFORM_WINDOWSstd::wstring wstr;wstr.resize(conStr.size());OemToCharBuffW(&conStr[0],&wstr[0],conStr.size());return WStrToUtf8(wstr,utf8str);#else// not implemented yetutf8str = conStr;return true;#endif}bool Utf8FitTo(const std::string& str, std::wstring search){std::wstring temp;if(!Utf8toWStr(str,temp))return false;// converting to lower casewstrToLower( 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(stdout, str, &ap);va_end(ap);}void vutf8printf(FILE *out, const char *str, va_list* ap){#if PLATFORM == PLATFORM_WINDOWSchar temp_buf[32*1024];wchar_t wtemp_buf[32*1024];size_t temp_len = vsnprintf(temp_buf, 32*1024, str, *ap);size_t wtemp_len = 32*1024-1;Utf8toWStr(temp_buf, temp_len, wtemp_buf, wtemp_len);CharToOemBuffW(&wtemp_buf[0], &temp_buf[0], wtemp_len+1);fprintf(out, "%s", temp_buf);#elsevfprintf(out, str, *ap);#endif}void hexEncodeByteArray(uint8* bytes, uint32 arrayLen, std::string& result){std::ostringstream ss;for(uint32 i=0; i<arrayLen; ++i){for(uint8 j=0; j<2; ++j){unsigned char nibble = 0x0F & (bytes[i]>>((1-j)*4));char encodedNibble;if(nibble < 0x0A)encodedNibble = '0'+nibble;elseencodedNibble = 'A'+nibble-0x0A;ss << encodedNibble;}}result = ss.str();}
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。