[7833] Implement levelup spells for non-hunter pets.
[getmangos.git] / src / shared / Util.cpp
blobfa18ad9bd5cf00ec2eed49fabff9a3086d18bd3c
1 /*
2 * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 #include "Util.h"
21 #include "sockets/socket_include.h"
22 #include "utf8cpp/utf8.h"
23 #include "mersennetwister/MersenneTwister.h"
24 #include <ace/TSS_T.h>
26 typedef ACE_TSS<MTRand> MTRandTSS;
27 static MTRandTSS mtRand;
29 int32 irand (int32 min, int32 max)
31 return int32 (mtRand->randInt (max - min)) + min;
34 uint32 urand (uint32 min, uint32 max)
36 return mtRand->randInt (max - min) + min;
39 int32 rand32 ()
41 return mtRand->randInt ();
44 double rand_norm(void)
46 return mtRand->randExc ();
49 double rand_chance (void)
51 return mtRand->randExc (100.0);
54 Tokens StrSplit(const std::string &src, const std::string &sep)
56 Tokens r;
57 std::string s;
58 for (std::string::const_iterator i = src.begin(); i != src.end(); i++)
60 if (sep.find(*i) != std::string::npos)
62 if (s.length()) r.push_back(s);
63 s = "";
65 else
67 s += *i;
70 if (s.length()) r.push_back(s);
71 return r;
74 void stripLineInvisibleChars(std::string &str)
76 static std::string invChars = " \t\7";
78 size_t wpos = 0;
80 bool space = false;
81 for(size_t pos = 0; pos < str.size(); ++pos)
83 if(invChars.find(str[pos])!=std::string::npos)
85 if(!space)
87 str[wpos++] = ' ';
88 space = true;
91 else
93 if(wpos!=pos)
94 str[wpos++] = str[pos];
95 else
96 ++wpos;
97 space = false;
101 if(wpos < str.size())
102 str.erase(wpos,str.size());
105 std::string secsToTimeString(uint32 timeInSecs, bool shortText, bool hoursOnly)
107 uint32 secs = timeInSecs % MINUTE;
108 uint32 minutes = timeInSecs % HOUR / MINUTE;
109 uint32 hours = timeInSecs % DAY / HOUR;
110 uint32 days = timeInSecs / DAY;
112 std::ostringstream ss;
113 if(days)
114 ss << days << (shortText ? "d" : " Day(s) ");
115 if(hours || hoursOnly)
116 ss << hours << (shortText ? "h" : " Hour(s) ");
117 if(!hoursOnly)
119 if(minutes)
120 ss << minutes << (shortText ? "m" : " Minute(s) ");
121 if(secs || (!days && !hours && !minutes) )
122 ss << secs << (shortText ? "s" : " Second(s).");
125 return ss.str();
128 uint32 TimeStringToSecs(const std::string& timestring)
130 uint32 secs = 0;
131 uint32 buffer = 0;
132 uint32 multiplier = 0;
134 for(std::string::const_iterator itr = timestring.begin(); itr != timestring.end(); itr++ )
136 if(isdigit(*itr))
138 std::string str; //very complicated typecast char->const char*; is there no better way?
139 str += *itr;
140 const char* tmp = str.c_str();
142 buffer*=10;
143 buffer+=atoi(tmp);
145 else
147 switch(*itr)
149 case 'd': multiplier = DAY; break;
150 case 'h': multiplier = HOUR; break;
151 case 'm': multiplier = MINUTE; break;
152 case 's': multiplier = 1; break;
153 default : return 0; //bad format
155 buffer*=multiplier;
156 secs+=buffer;
157 buffer=0;
161 return secs;
164 std::string TimeToTimestampStr(time_t t)
166 tm* aTm = localtime(&t);
167 // YYYY year
168 // MM month (2 digits 01-12)
169 // DD day (2 digits 01-31)
170 // HH hour (2 digits 00-23)
171 // MM minutes (2 digits 00-59)
172 // SS seconds (2 digits 00-59)
173 char buf[20];
174 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);
175 return std::string(buf);
178 /// Check if the string is a valid ip address representation
179 bool IsIPAddress(char const* ipaddress)
181 if(!ipaddress)
182 return false;
184 // Let the big boys do it.
185 // Drawback: all valid ip address formats are recognized e.g.: 12.23,121234,0xABCD)
186 return inet_addr(ipaddress) != INADDR_NONE;
189 /// create PID file
190 uint32 CreatePIDFile(const std::string& filename)
192 FILE * pid_file = fopen (filename.c_str(), "w" );
193 if (pid_file == NULL)
194 return 0;
196 #ifdef WIN32
197 DWORD pid = GetCurrentProcessId();
198 #else
199 pid_t pid = getpid();
200 #endif
202 fprintf(pid_file, "%d", pid );
203 fclose(pid_file);
205 return (uint32)pid;
208 size_t utf8length(std::string& utf8str)
212 return utf8::distance(utf8str.c_str(),utf8str.c_str()+utf8str.size());
214 catch(std::exception)
216 utf8str = "";
217 return 0;
221 void utf8truncate(std::string& utf8str,size_t len)
225 size_t wlen = utf8::distance(utf8str.c_str(),utf8str.c_str()+utf8str.size());
226 if(wlen <= len)
227 return;
229 std::wstring wstr;
230 wstr.resize(wlen);
231 utf8::utf8to16(utf8str.c_str(),utf8str.c_str()+utf8str.size(),&wstr[0]);
232 wstr.resize(len);
233 char* oend = utf8::utf16to8(wstr.c_str(),wstr.c_str()+wstr.size(),&utf8str[0]);
234 utf8str.resize(oend-(&utf8str[0])); // remove unused tail
236 catch(std::exception)
238 utf8str = "";
242 bool Utf8toWStr(char const* utf8str, size_t csize, wchar_t* wstr, size_t& wsize)
246 size_t len = utf8::distance(utf8str,utf8str+csize);
247 if(len > wsize)
249 if(wsize > 0)
250 wstr[0] = L'\0';
251 wsize = 0;
252 return false;
255 wsize = len;
256 utf8::utf8to16(utf8str,utf8str+csize,wstr);
257 wstr[len] = L'\0';
259 catch(std::exception)
261 if(wsize > 0)
262 wstr[0] = L'\0';
263 wsize = 0;
264 return false;
267 return true;
270 bool Utf8toWStr(const std::string& utf8str, std::wstring& wstr)
274 size_t len = utf8::distance(utf8str.c_str(),utf8str.c_str()+utf8str.size());
275 wstr.resize(len);
277 utf8::utf8to16(utf8str.c_str(),utf8str.c_str()+utf8str.size(),&wstr[0]);
279 catch(std::exception)
281 wstr = L"";
282 return false;
285 return true;
288 bool WStrToUtf8(wchar_t* wstr, size_t size, std::string& utf8str)
292 std::string utf8str2;
293 utf8str2.resize(size*4); // allocate for most long case
295 char* oend = utf8::utf16to8(wstr,wstr+size,&utf8str2[0]);
296 utf8str2.resize(oend-(&utf8str2[0])); // remove unused tail
297 utf8str = utf8str2;
299 catch(std::exception)
301 utf8str = "";
302 return false;
305 return true;
308 bool WStrToUtf8(std::wstring wstr, std::string& utf8str)
312 std::string utf8str2;
313 utf8str2.resize(wstr.size()*4); // allocate for most long case
315 char* oend = utf8::utf16to8(wstr.c_str(),wstr.c_str()+wstr.size(),&utf8str2[0]);
316 utf8str2.resize(oend-(&utf8str2[0])); // remove unused tail
317 utf8str = utf8str2;
319 catch(std::exception)
321 utf8str = "";
322 return false;
325 return true;
328 typedef wchar_t const* const* wstrlist;
330 std::wstring GetMainPartOfName(std::wstring wname, uint32 declension)
332 // supported only Cyrillic cases
333 if(wname.size() < 1 || !isCyrillicCharacter(wname[0]) || declension > 5)
334 return wname;
336 // Important: end length must be <= MAX_INTERNAL_PLAYER_NAME-MAX_PLAYER_NAME (3 currently)
338 static wchar_t const a_End[] = { wchar_t(1), wchar_t(0x0430),wchar_t(0x0000)};
339 static wchar_t const o_End[] = { wchar_t(1), wchar_t(0x043E),wchar_t(0x0000)};
340 static wchar_t const ya_End[] = { wchar_t(1), wchar_t(0x044F),wchar_t(0x0000)};
341 static wchar_t const ie_End[] = { wchar_t(1), wchar_t(0x0435),wchar_t(0x0000)};
342 static wchar_t const i_End[] = { wchar_t(1), wchar_t(0x0438),wchar_t(0x0000)};
343 static wchar_t const yeru_End[] = { wchar_t(1), wchar_t(0x044B),wchar_t(0x0000)};
344 static wchar_t const u_End[] = { wchar_t(1), wchar_t(0x0443),wchar_t(0x0000)};
345 static wchar_t const yu_End[] = { wchar_t(1), wchar_t(0x044E),wchar_t(0x0000)};
346 static wchar_t const oj_End[] = { wchar_t(2), wchar_t(0x043E),wchar_t(0x0439),wchar_t(0x0000)};
347 static wchar_t const ie_j_End[] = { wchar_t(2), wchar_t(0x0435),wchar_t(0x0439),wchar_t(0x0000)};
348 static wchar_t const io_j_End[] = { wchar_t(2), wchar_t(0x0451),wchar_t(0x0439),wchar_t(0x0000)};
349 static wchar_t const o_m_End[] = { wchar_t(2), wchar_t(0x043E),wchar_t(0x043C),wchar_t(0x0000)};
350 static wchar_t const io_m_End[] = { wchar_t(2), wchar_t(0x0451),wchar_t(0x043C),wchar_t(0x0000)};
351 static wchar_t const ie_m_End[] = { wchar_t(2), wchar_t(0x0435),wchar_t(0x043C),wchar_t(0x0000)};
352 static wchar_t const soft_End[] = { wchar_t(1), wchar_t(0x044C),wchar_t(0x0000)};
353 static wchar_t const j_End[] = { wchar_t(1), wchar_t(0x0439),wchar_t(0x0000)};
355 static wchar_t const* const dropEnds[6][8] = {
356 { &a_End[1], &o_End[1], &ya_End[1], &ie_End[1], &soft_End[1], &j_End[1], NULL, NULL },
357 { &a_End[1], &ya_End[1], &yeru_End[1], &i_End[1], NULL, NULL, NULL, NULL },
358 { &ie_End[1], &u_End[1], &yu_End[1], &i_End[1], NULL, NULL, NULL, NULL },
359 { &u_End[1], &yu_End[1], &o_End[1], &ie_End[1], &soft_End[1], &ya_End[1], &a_End[1], NULL },
360 { &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 },
361 { &ie_End[1], &i_End[1], NULL, NULL, NULL, NULL, NULL, NULL }
364 for(wchar_t const * const* itr = &dropEnds[declension][0]; *itr; ++itr)
366 size_t len = size_t((*itr)[-1]); // get length from string size field
368 if(wname.substr(wname.size()-len,len)==*itr)
369 return wname.substr(0,wname.size()-len);
372 return wname;
375 bool utf8ToConsole(const std::string& utf8str, std::string& conStr)
377 #if PLATFORM == PLATFORM_WINDOWS
378 std::wstring wstr;
379 if(!Utf8toWStr(utf8str,wstr))
380 return false;
382 conStr.resize(wstr.size());
383 CharToOemBuffW(&wstr[0],&conStr[0],wstr.size());
384 #else
385 // not implemented yet
386 conStr = utf8str;
387 #endif
389 return true;
392 bool consoleToUtf8(const std::string& conStr,std::string& utf8str)
394 #if PLATFORM == PLATFORM_WINDOWS
395 std::wstring wstr;
396 wstr.resize(conStr.size());
397 OemToCharBuffW(&conStr[0],&wstr[0],conStr.size());
399 return WStrToUtf8(wstr,utf8str);
400 #else
401 // not implemented yet
402 utf8str = conStr;
403 return true;
404 #endif
407 bool Utf8FitTo(const std::string& str, std::wstring search)
409 std::wstring temp;
411 if(!Utf8toWStr(str,temp))
412 return false;
414 // converting to lower case
415 wstrToLower( temp );
417 if(temp.find(search) == std::wstring::npos)
418 return false;
420 return true;