merged the content type extension and delta
[oweals/minetest.git] / src / utility.h
1 /*
2 Minetest-c55
3 Copyright (C) 2010 celeron55, Perttu Ahola <celeron55@gmail.com>
4
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License along
16 with this program; if not, write to the Free Software Foundation, Inc.,
17 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18 */
19
20 #ifndef UTILITY_HEADER
21 #define UTILITY_HEADER
22
23 #include <iostream>
24 #include <fstream>
25 #include <string>
26 #include <sstream>
27 #include <vector>
28 #include <jthread.h>
29 #include <jmutex.h>
30 #include <jmutexautolock.h>
31
32 #include "common_irrlicht.h"
33 #include "debug.h"
34 #include "strfnd.h"
35 #include "exceptions.h"
36 #include "porting.h"
37
38 extern const v3s16 g_6dirs[6];
39
40 extern const v3s16 g_26dirs[26];
41
42 // 26th is (0,0,0)
43 extern const v3s16 g_27dirs[27];
44
45 inline void writeU64(u8 *data, u64 i)
46 {
47         data[0] = ((i>>56)&0xff);
48         data[1] = ((i>>48)&0xff);
49         data[2] = ((i>>40)&0xff);
50         data[3] = ((i>>32)&0xff);
51         data[4] = ((i>>24)&0xff);
52         data[5] = ((i>>16)&0xff);
53         data[6] = ((i>> 8)&0xff);
54         data[7] = ((i>> 0)&0xff);
55 }
56
57 inline void writeU32(u8 *data, u32 i)
58 {
59         data[0] = ((i>>24)&0xff);
60         data[1] = ((i>>16)&0xff);
61         data[2] = ((i>> 8)&0xff);
62         data[3] = ((i>> 0)&0xff);
63 }
64
65 inline void writeU16(u8 *data, u16 i)
66 {
67         data[0] = ((i>> 8)&0xff);
68         data[1] = ((i>> 0)&0xff);
69 }
70
71 inline void writeU8(u8 *data, u8 i)
72 {
73         data[0] = ((i>> 0)&0xff);
74 }
75
76 inline u64 readU64(u8 *data)
77 {
78         return ((u64)data[0]<<56) | ((u64)data[1]<<48)
79                 | ((u64)data[2]<<40) | ((u64)data[3]<<32)
80                 | ((u64)data[4]<<24) | ((u64)data[5]<<16)
81                 | ((u64)data[6]<<8) | ((u64)data[7]<<0);
82 }
83
84 inline u32 readU32(u8 *data)
85 {
86         return (data[0]<<24) | (data[1]<<16) | (data[2]<<8) | (data[3]<<0);
87 }
88
89 inline u16 readU16(u8 *data)
90 {
91         return (data[0]<<8) | (data[1]<<0);
92 }
93
94 inline u8 readU8(u8 *data)
95 {
96         return (data[0]<<0);
97 }
98
99 inline void writeS32(u8 *data, s32 i){
100         writeU32(data, (u32)i);
101 }
102 inline s32 readS32(u8 *data){
103         return (s32)readU32(data);
104 }
105
106 inline void writeF1000(u8 *data, f32 i){
107         writeS32(data, i*1000);
108 }
109 inline f32 readF1000(u8 *data){
110         return (f32)readS32(data)/1000.;
111 }
112
113 inline void writeS16(u8 *data, s16 i){
114         writeU16(data, (u16)i);
115 }
116 inline s16 readS16(u8 *data){
117         return (s16)readU16(data);
118 }
119
120 inline void writeV3S32(u8 *data, v3s32 p)
121 {
122         writeS32(&data[0], p.X);
123         writeS32(&data[4], p.Y);
124         writeS32(&data[8], p.Z);
125 }
126 inline v3s32 readV3S32(u8 *data)
127 {
128         v3s32 p;
129         p.X = readS32(&data[0]);
130         p.Y = readS32(&data[4]);
131         p.Z = readS32(&data[8]);
132         return p;
133 }
134
135 inline void writeV3F1000(u8 *data, v3f p)
136 {
137         writeF1000(&data[0], p.X);
138         writeF1000(&data[4], p.Y);
139         writeF1000(&data[8], p.Z);
140 }
141 inline v3f readV3F1000(u8 *data)
142 {
143         v3f p;
144         p.X = (float)readF1000(&data[0]);
145         p.Y = (float)readF1000(&data[4]);
146         p.Z = (float)readF1000(&data[8]);
147         return p;
148 }
149
150 inline void writeV2S16(u8 *data, v2s16 p)
151 {
152         writeS16(&data[0], p.X);
153         writeS16(&data[2], p.Y);
154 }
155
156 inline v2s16 readV2S16(u8 *data)
157 {
158         v2s16 p;
159         p.X = readS16(&data[0]);
160         p.Y = readS16(&data[2]);
161         return p;
162 }
163
164 inline void writeV2S32(u8 *data, v2s32 p)
165 {
166         writeS32(&data[0], p.X);
167         writeS32(&data[2], p.Y);
168 }
169
170 inline v2s32 readV2S32(u8 *data)
171 {
172         v2s32 p;
173         p.X = readS32(&data[0]);
174         p.Y = readS32(&data[2]);
175         return p;
176 }
177
178 inline void writeV3S16(u8 *data, v3s16 p)
179 {
180         writeS16(&data[0], p.X);
181         writeS16(&data[2], p.Y);
182         writeS16(&data[4], p.Z);
183 }
184
185 inline v3s16 readV3S16(u8 *data)
186 {
187         v3s16 p;
188         p.X = readS16(&data[0]);
189         p.Y = readS16(&data[2]);
190         p.Z = readS16(&data[4]);
191         return p;
192 }
193
194 /*
195         The above stuff directly interfaced to iostream
196 */
197
198 inline void writeU8(std::ostream &os, u8 p)
199 {
200         char buf[1];
201         writeU8((u8*)buf, p);
202         os.write(buf, 1);
203 }
204 inline u8 readU8(std::istream &is)
205 {
206         char buf[1];
207         is.read(buf, 1);
208         return readU8((u8*)buf);
209 }
210
211 inline void writeU16(std::ostream &os, u16 p)
212 {
213         char buf[2];
214         writeU16((u8*)buf, p);
215         os.write(buf, 2);
216 }
217 inline u16 readU16(std::istream &is)
218 {
219         char buf[2];
220         is.read(buf, 2);
221         return readU16((u8*)buf);
222 }
223
224 inline void writeU32(std::ostream &os, u16 p)
225 {
226         char buf[4];
227         writeU16((u8*)buf, p);
228         os.write(buf, 4);
229 }
230 inline u16 readU32(std::istream &is)
231 {
232         char buf[4];
233         is.read(buf, 4);
234         return readU32((u8*)buf);
235 }
236
237 inline void writeF1000(std::ostream &os, f32 p)
238 {
239         char buf[2];
240         writeF1000((u8*)buf, p);
241         os.write(buf, 2);
242 }
243 inline f32 readF1000(std::istream &is)
244 {
245         char buf[2];
246         is.read(buf, 2);
247         // TODO: verify if this gets rid of the valgrind warning
248         //if(is.gcount() != 2)
249         //      return 0;
250         return readF1000((u8*)buf);
251 }
252
253 inline void writeV3F1000(std::ostream &os, v3f p)
254 {
255         char buf[12];
256         writeV3F1000((u8*)buf, p);
257         os.write(buf, 12);
258 }
259 inline v3f readV3F1000(std::istream &is)
260 {
261         char buf[12];
262         is.read(buf, 12);
263         return readV3F1000((u8*)buf);
264 }
265
266 /*
267         None of these are used at the moment
268 */
269
270 template <typename T>
271 class SharedPtr
272 {
273 public:
274         SharedPtr(T *t=NULL)
275         {
276                 refcount = new int;
277                 *refcount = 1;
278                 ptr = t;
279         }
280         SharedPtr(SharedPtr<T> &t)
281         {
282                 //*this = t;
283                 drop();
284                 refcount = t.refcount;
285                 (*refcount)++;
286                 ptr = t.ptr;
287         }
288         ~SharedPtr()
289         {
290                 drop();
291         }
292         SharedPtr<T> & operator=(T *t)
293         {
294                 drop();
295                 refcount = new int;
296                 *refcount = 1;
297                 ptr = t;
298                 return *this;
299         }
300         SharedPtr<T> & operator=(SharedPtr<T> &t)
301         {
302                 drop();
303                 refcount = t.refcount;
304                 (*refcount)++;
305                 ptr = t.ptr;
306                 return *this;
307         }
308         T* operator->()
309         {
310                 return ptr;
311         }
312         T & operator*()
313         {
314                 return *ptr;
315         }
316         bool operator!=(T *t)
317         {
318                 return ptr != t;
319         }
320         bool operator==(T *t)
321         {
322                 return ptr == t;
323         }
324         T & operator[](unsigned int i)
325         {
326                 return ptr[i];
327         }
328 private:
329         void drop()
330         {
331                 assert((*refcount) > 0);
332                 (*refcount)--;
333                 if(*refcount == 0)
334                 {
335                         delete refcount;
336                         if(ptr != NULL)
337                                 delete ptr;
338                 }
339         }
340         T *ptr;
341         int *refcount;
342 };
343
344 template <typename T>
345 class Buffer
346 {
347 public:
348         Buffer(unsigned int size)
349         {
350                 m_size = size;
351                 data = new T[size];
352         }
353         Buffer(const Buffer &buffer)
354         {
355                 m_size = buffer.m_size;
356                 data = new T[buffer.m_size];
357                 memcpy(data, buffer.data, buffer.m_size);
358         }
359         Buffer(T *t, unsigned int size)
360         {
361                 m_size = size;
362                 data = new T[size];
363                 memcpy(data, t, size);
364         }
365         ~Buffer()
366         {
367                 delete[] data;
368         }
369         T & operator[](unsigned int i) const
370         {
371                 return data[i];
372         }
373         T * operator*() const
374         {
375                 return data;
376         }
377         unsigned int getSize() const
378         {
379                 return m_size;
380         }
381 private:
382         T *data;
383         unsigned int m_size;
384 };
385
386 template <typename T>
387 class SharedBuffer
388 {
389 public:
390         SharedBuffer()
391         {
392                 m_size = 0;
393                 data = NULL;
394                 refcount = new unsigned int;
395                 (*refcount) = 1;
396         }
397         SharedBuffer(unsigned int size)
398         {
399                 m_size = size;
400                 if(m_size != 0)
401                         data = new T[m_size];
402                 else
403                         data = NULL;
404                 refcount = new unsigned int;
405                 (*refcount) = 1;
406         }
407         SharedBuffer(const SharedBuffer &buffer)
408         {
409                 //std::cout<<"SharedBuffer(const SharedBuffer &buffer)"<<std::endl;
410                 m_size = buffer.m_size;
411                 data = buffer.data;
412                 refcount = buffer.refcount;
413                 (*refcount)++;
414         }
415         SharedBuffer & operator=(const SharedBuffer & buffer)
416         {
417                 //std::cout<<"SharedBuffer & operator=(const SharedBuffer & buffer)"<<std::endl;
418                 if(this == &buffer)
419                         return *this;
420                 drop();
421                 m_size = buffer.m_size;
422                 data = buffer.data;
423                 refcount = buffer.refcount;
424                 (*refcount)++;
425                 return *this;
426         }
427         /*
428                 Copies whole buffer
429         */
430         SharedBuffer(T *t, unsigned int size)
431         {
432                 m_size = size;
433                 if(m_size != 0)
434                 {
435                         data = new T[m_size];
436                         memcpy(data, t, m_size);
437                 }
438                 else
439                         data = NULL;
440                 refcount = new unsigned int;
441                 (*refcount) = 1;
442         }
443         /*
444                 Copies whole buffer
445         */
446         SharedBuffer(const Buffer<T> &buffer)
447         {
448                 m_size = buffer.getSize();
449                 if(m_size != 0)
450                 {
451                         data = new T[m_size];
452                         memcpy(data, *buffer, buffer.getSize());
453                 }
454                 else
455                         data = NULL;
456                 refcount = new unsigned int;
457                 (*refcount) = 1;
458         }
459         ~SharedBuffer()
460         {
461                 drop();
462         }
463         T & operator[](unsigned int i) const
464         {
465                 //assert(i < m_size)
466                 return data[i];
467         }
468         T * operator*() const
469         {
470                 return data;
471         }
472         unsigned int getSize() const
473         {
474                 return m_size;
475         }
476 private:
477         void drop()
478         {
479                 assert((*refcount) > 0);
480                 (*refcount)--;
481                 if(*refcount == 0)
482                 {
483                         if(data)
484                                 delete[] data;
485                         delete refcount;
486                 }
487         }
488         T *data;
489         unsigned int m_size;
490         unsigned int *refcount;
491 };
492
493 inline SharedBuffer<u8> SharedBufferFromString(const char *string)
494 {
495         SharedBuffer<u8> b((u8*)string, strlen(string)+1);
496         return b;
497 }
498
499 template<typename T>
500 class MutexedVariable
501 {
502 public:
503         MutexedVariable(T value):
504                 m_value(value)
505         {
506                 m_mutex.Init();
507         }
508
509         T get()
510         {
511                 JMutexAutoLock lock(m_mutex);
512                 return m_value;
513         }
514
515         void set(T value)
516         {
517                 JMutexAutoLock lock(m_mutex);
518                 m_value = value;
519         }
520         
521         // You'll want to grab this in a SharedPtr
522         JMutexAutoLock * getLock()
523         {
524                 return new JMutexAutoLock(m_mutex);
525         }
526         
527         // You pretty surely want to grab the lock when accessing this
528         T m_value;
529
530 private:
531         JMutex m_mutex;
532 };
533
534 /*
535         TimeTaker
536 */
537
538 class TimeTaker
539 {
540 public:
541         TimeTaker(const char *name, u32 *result=NULL);
542
543         ~TimeTaker()
544         {
545                 stop();
546         }
547
548         u32 stop(bool quiet=false);
549
550         u32 getTime();
551
552 private:
553         const char *m_name;
554         u32 m_time1;
555         bool m_running;
556         u32 *m_result;
557 };
558
559 // Calculates the borders of a "d-radius" cube
560 inline void getFacePositions(core::list<v3s16> &list, u16 d)
561 {
562         if(d == 0)
563         {
564                 list.push_back(v3s16(0,0,0));
565                 return;
566         }
567         if(d == 1)
568         {
569                 /*
570                         This is an optimized sequence of coordinates.
571                 */
572                 list.push_back(v3s16( 0, 1, 0)); // top
573                 list.push_back(v3s16( 0, 0, 1)); // back
574                 list.push_back(v3s16(-1, 0, 0)); // left
575                 list.push_back(v3s16( 1, 0, 0)); // right
576                 list.push_back(v3s16( 0, 0,-1)); // front
577                 list.push_back(v3s16( 0,-1, 0)); // bottom
578                 // 6
579                 list.push_back(v3s16(-1, 0, 1)); // back left
580                 list.push_back(v3s16( 1, 0, 1)); // back right
581                 list.push_back(v3s16(-1, 0,-1)); // front left
582                 list.push_back(v3s16( 1, 0,-1)); // front right
583                 list.push_back(v3s16(-1,-1, 0)); // bottom left
584                 list.push_back(v3s16( 1,-1, 0)); // bottom right
585                 list.push_back(v3s16( 0,-1, 1)); // bottom back
586                 list.push_back(v3s16( 0,-1,-1)); // bottom front
587                 list.push_back(v3s16(-1, 1, 0)); // top left
588                 list.push_back(v3s16( 1, 1, 0)); // top right
589                 list.push_back(v3s16( 0, 1, 1)); // top back
590                 list.push_back(v3s16( 0, 1,-1)); // top front
591                 // 18
592                 list.push_back(v3s16(-1, 1, 1)); // top back-left
593                 list.push_back(v3s16( 1, 1, 1)); // top back-right
594                 list.push_back(v3s16(-1, 1,-1)); // top front-left
595                 list.push_back(v3s16( 1, 1,-1)); // top front-right
596                 list.push_back(v3s16(-1,-1, 1)); // bottom back-left
597                 list.push_back(v3s16( 1,-1, 1)); // bottom back-right
598                 list.push_back(v3s16(-1,-1,-1)); // bottom front-left
599                 list.push_back(v3s16( 1,-1,-1)); // bottom front-right
600                 // 26
601                 return;
602         }
603
604         // Take blocks in all sides, starting from y=0 and going +-y
605         for(s16 y=0; y<=d-1; y++)
606         {
607                 // Left and right side, including borders
608                 for(s16 z=-d; z<=d; z++)
609                 {
610                         list.push_back(v3s16(d,y,z));
611                         list.push_back(v3s16(-d,y,z));
612                         if(y != 0)
613                         {
614                                 list.push_back(v3s16(d,-y,z));
615                                 list.push_back(v3s16(-d,-y,z));
616                         }
617                 }
618                 // Back and front side, excluding borders
619                 for(s16 x=-d+1; x<=d-1; x++)
620                 {
621                         list.push_back(v3s16(x,y,d));
622                         list.push_back(v3s16(x,y,-d));
623                         if(y != 0)
624                         {
625                                 list.push_back(v3s16(x,-y,d));
626                                 list.push_back(v3s16(x,-y,-d));
627                         }
628                 }
629         }
630
631         // Take the bottom and top face with borders
632         // -d<x<d, y=+-d, -d<z<d
633         for(s16 x=-d; x<=d; x++)
634         for(s16 z=-d; z<=d; z++)
635         {
636                 list.push_back(v3s16(x,-d,z));
637                 list.push_back(v3s16(x,d,z));
638         }
639 }
640
641 class IndentationRaiser
642 {
643 public:
644         IndentationRaiser(u16 *indentation)
645         {
646                 m_indentation = indentation;
647                 (*m_indentation)++;
648         }
649         ~IndentationRaiser()
650         {
651                 (*m_indentation)--;
652         }
653 private:
654         u16 *m_indentation;
655 };
656
657 inline s16 getContainerPos(s16 p, s16 d)
658 {
659         return (p>=0 ? p : p-d+1) / d;
660 }
661
662 inline v2s16 getContainerPos(v2s16 p, s16 d)
663 {
664         return v2s16(
665                 getContainerPos(p.X, d),
666                 getContainerPos(p.Y, d)
667         );
668 }
669
670 inline v3s16 getContainerPos(v3s16 p, s16 d)
671 {
672         return v3s16(
673                 getContainerPos(p.X, d),
674                 getContainerPos(p.Y, d),
675                 getContainerPos(p.Z, d)
676         );
677 }
678
679 inline v2s16 getContainerPos(v2s16 p, v2s16 d)
680 {
681         return v2s16(
682                 getContainerPos(p.X, d.X),
683                 getContainerPos(p.Y, d.Y)
684         );
685 }
686
687 inline v3s16 getContainerPos(v3s16 p, v3s16 d)
688 {
689         return v3s16(
690                 getContainerPos(p.X, d.X),
691                 getContainerPos(p.Y, d.Y),
692                 getContainerPos(p.Z, d.Z)
693         );
694 }
695
696 inline bool isInArea(v3s16 p, s16 d)
697 {
698         return (
699                 p.X >= 0 && p.X < d &&
700                 p.Y >= 0 && p.Y < d &&
701                 p.Z >= 0 && p.Z < d
702         );
703 }
704
705 inline bool isInArea(v2s16 p, s16 d)
706 {
707         return (
708                 p.X >= 0 && p.X < d &&
709                 p.Y >= 0 && p.Y < d
710         );
711 }
712
713 inline bool isInArea(v3s16 p, v3s16 d)
714 {
715         return (
716                 p.X >= 0 && p.X < d.X &&
717                 p.Y >= 0 && p.Y < d.Y &&
718                 p.Z >= 0 && p.Z < d.Z
719         );
720 }
721
722 inline s16 rangelim(s16 i, s16 max)
723 {
724         if(i < 0)
725                 return 0;
726         if(i > max)
727                 return max;
728         return i;
729 }
730
731 #define rangelim(d, min, max) ((d) < (min) ? (min) : ((d)>(max)?(max):(d)))
732
733 inline v3s16 arealim(v3s16 p, s16 d)
734 {
735         if(p.X < 0)
736                 p.X = 0;
737         if(p.Y < 0)
738                 p.Y = 0;
739         if(p.Z < 0)
740                 p.Z = 0;
741         if(p.X > d-1)
742                 p.X = d-1;
743         if(p.Y > d-1)
744                 p.Y = d-1;
745         if(p.Z > d-1)
746                 p.Z = d-1;
747         return p;
748 }
749
750 inline std::wstring narrow_to_wide(const std::string& mbs)
751 {
752         size_t wcl = mbs.size();
753         Buffer<wchar_t> wcs(wcl+1);
754         size_t l = mbstowcs(*wcs, mbs.c_str(), wcl);
755         if(l == (size_t)(-1))
756                 return L"<invalid multibyte string>";
757         wcs[l] = 0;
758         return *wcs;
759 }
760
761 inline std::string wide_to_narrow(const std::wstring& wcs)
762 {
763         size_t mbl = wcs.size()*4;
764         SharedBuffer<char> mbs(mbl+1);
765         size_t l = wcstombs(*mbs, wcs.c_str(), mbl);
766         if(l == (size_t)(-1))
767                 mbs[0] = 0;
768         else
769                 mbs[l] = 0;
770         return *mbs;
771 }
772
773 // Split a string using the given delimiter. Returns a vector containing
774 // the component parts.
775 inline std::vector<std::wstring> str_split(const std::wstring &str, wchar_t delimiter)
776 {
777         std::vector<std::wstring> parts;
778         std::wstringstream sstr(str);
779         std::wstring part;
780         while(std::getline(sstr, part, delimiter))
781                 parts.push_back(part);
782         return parts;
783 }
784
785
786 /*
787         See test.cpp for example cases.
788         wraps degrees to the range of -360...360
789         NOTE: Wrapping to 0...360 is not used because pitch needs negative values.
790 */
791 inline float wrapDegrees(float f)
792 {
793         // Take examples of f=10, f=720.5, f=-0.5, f=-360.5
794         // This results in
795         // 10, 720, -1, -361
796         int i = floor(f);
797         // 0, 2, 0, -1
798         int l = i / 360;
799         // NOTE: This would be used for wrapping to 0...360
800         // 0, 2, -1, -2
801         /*if(i < 0)
802                 l -= 1;*/
803         // 0, 720, 0, -360
804         int k = l * 360;
805         // 10, 0.5, -0.5, -0.5
806         f -= float(k);
807         return f;
808 }
809
810 inline std::string lowercase(const std::string &s)
811 {
812         std::string s2;
813         for(size_t i=0; i<s.size(); i++)
814         {
815                 char c = s[i];
816                 if(c >= 'A' && c <= 'Z')
817                         c -= 'A' - 'a';
818                 s2 += c;
819         }
820         return s2;
821 }
822
823 inline bool is_yes(const std::string &s)
824 {
825         std::string s2 = lowercase(trim(s));
826         if(s2 == "y" || s2 == "yes" || s2 == "true" || s2 == "1")
827                 return true;
828         return false;
829 }
830
831 inline s32 stoi(const std::string &s, s32 min, s32 max)
832 {
833         s32 i = atoi(s.c_str());
834         if(i < min)
835                 i = min;
836         if(i > max)
837                 i = max;
838         return i;
839 }
840
841
842 // MSVC2010 includes it's own versions of these
843 #if !defined(_MSC_VER) || _MSC_VER < 1600
844
845 inline s32 stoi(std::string s)
846 {
847         return atoi(s.c_str());
848 }
849
850 inline s32 stoi(std::wstring s)
851 {
852         return atoi(wide_to_narrow(s).c_str());
853 }
854
855 inline float stof(std::string s)
856 {
857         float f;
858         std::istringstream ss(s);
859         ss>>f;
860         return f;
861 }
862
863 #endif
864
865 inline std::string itos(s32 i)
866 {
867         std::ostringstream o;
868         o<<i;
869         return o.str();
870 }
871
872 inline std::string ftos(float f)
873 {
874         std::ostringstream o;
875         o<<f;
876         return o.str();
877 }
878
879 inline void str_replace(std::string & str, std::string const & pattern,
880                 std::string const & replacement)
881 {
882         std::string::size_type start = str.find(pattern, 0);
883         while(start != str.npos)
884         {
885                 str.replace(start, pattern.size(), replacement);
886                 start = str.find(pattern, start+replacement.size());
887         }
888 }
889
890 inline void str_replace_char(std::string & str, char from, char to)
891 {
892         for(unsigned int i=0; i<str.size(); i++)
893         {
894                 if(str[i] == from)
895                         str[i] = to;
896         }
897 }
898
899 /*
900         A base class for simple background thread implementation
901 */
902
903 class SimpleThread : public JThread
904 {
905         bool run;
906         JMutex run_mutex;
907
908 public:
909
910         SimpleThread():
911                 JThread(),
912                 run(true)
913         {
914                 run_mutex.Init();
915         }
916
917         virtual ~SimpleThread()
918         {}
919
920         virtual void * Thread() = 0;
921
922         bool getRun()
923         {
924                 JMutexAutoLock lock(run_mutex);
925                 return run;
926         }
927         void setRun(bool a_run)
928         {
929                 JMutexAutoLock lock(run_mutex);
930                 run = a_run;
931         }
932
933         void stop()
934         {
935                 setRun(false);
936                 while(IsRunning())
937                         sleep_ms(100);
938         }
939 };
940
941 /*
942         Config stuff
943 */
944
945 enum ValueType
946 {
947         VALUETYPE_STRING,
948         VALUETYPE_FLAG // Doesn't take any arguments
949 };
950
951 struct ValueSpec
952 {
953         ValueSpec(ValueType a_type, const char *a_help=NULL)
954         {
955                 type = a_type;
956                 help = a_help;
957         }
958         ValueType type;
959         const char *help;
960 };
961
962 class Settings
963 {
964 public:
965         Settings()
966         {
967                 m_mutex.Init();
968         }
969
970         void writeLines(std::ostream &os)
971         {
972                 JMutexAutoLock lock(m_mutex);
973                 
974                 for(core::map<std::string, std::string>::Iterator
975                                 i = m_settings.getIterator();
976                                 i.atEnd() == false; i++)
977                 {
978                         std::string name = i.getNode()->getKey();
979                         std::string value = i.getNode()->getValue();
980                         os<<name<<" = "<<value<<"\n";
981                 }
982         }
983
984         bool parseConfigLine(const std::string &line)
985         {
986                 JMutexAutoLock lock(m_mutex);
987                 
988                 std::string trimmedline = trim(line);
989                 
990                 // Ignore comments
991                 if(trimmedline[0] == '#')
992                         return true;
993
994                 //dstream<<"trimmedline=\""<<trimmedline<<"\""<<std::endl;
995
996                 Strfnd sf(trim(line));
997
998                 std::string name = sf.next("=");
999                 name = trim(name);
1000
1001                 if(name == "")
1002                         return true;
1003                 
1004                 std::string value = sf.next("\n");
1005                 value = trim(value);
1006
1007                 /*dstream<<"Config name=\""<<name<<"\" value=\""
1008                                 <<value<<"\""<<std::endl;*/
1009                 
1010                 m_settings[name] = value;
1011                 
1012                 return true;
1013         }
1014
1015         // Returns false on EOF
1016         bool parseConfigObject(std::istream &is)
1017         {
1018                 if(is.eof())
1019                         return false;
1020                 
1021                 /*
1022                         NOTE: This function might be expanded to allow multi-line
1023                               settings.
1024                 */
1025                 std::string line;
1026                 std::getline(is, line);
1027                 //dstream<<"got line: \""<<line<<"\""<<std::endl;
1028
1029                 return parseConfigLine(line);
1030         }
1031
1032         /*
1033                 Read configuration file
1034
1035                 Returns true on success
1036         */
1037         bool readConfigFile(const char *filename)
1038         {
1039                 std::ifstream is(filename);
1040                 if(is.good() == false)
1041                 {
1042                         dstream<<"Error opening configuration file \""
1043                                         <<filename<<"\""<<std::endl;
1044                         return false;
1045                 }
1046
1047                 dstream<<"Parsing configuration file: \""
1048                                 <<filename<<"\""<<std::endl;
1049                                 
1050                 while(parseConfigObject(is));
1051                 
1052                 return true;
1053         }
1054
1055         /*
1056                 Reads a configuration object from stream (usually a single line)
1057                 and adds it to dst.
1058                 
1059                 Preserves comments and empty lines.
1060
1061                 Settings that were added to dst are also added to updated.
1062                 key of updated is setting name, value of updated is dummy.
1063
1064                 Returns false on EOF
1065         */
1066         bool getUpdatedConfigObject(std::istream &is,
1067                         core::list<std::string> &dst,
1068                         core::map<std::string, bool> &updated)
1069         {
1070                 JMutexAutoLock lock(m_mutex);
1071                 
1072                 if(is.eof())
1073                         return false;
1074                 
1075                 // NOTE: This function will be expanded to allow multi-line settings
1076                 std::string line;
1077                 std::getline(is, line);
1078
1079                 std::string trimmedline = trim(line);
1080
1081                 std::string line_end = "";
1082                 if(is.eof() == false)
1083                         line_end = "\n";
1084                 
1085                 // Ignore comments
1086                 if(trimmedline[0] == '#')
1087                 {
1088                         dst.push_back(line+line_end);
1089                         return true;
1090                 }
1091
1092                 Strfnd sf(trim(line));
1093
1094                 std::string name = sf.next("=");
1095                 name = trim(name);
1096
1097                 if(name == "")
1098                 {
1099                         dst.push_back(line+line_end);
1100                         return true;
1101                 }
1102                 
1103                 std::string value = sf.next("\n");
1104                 value = trim(value);
1105                 
1106                 if(m_settings.find(name))
1107                 {
1108                         std::string newvalue = m_settings[name];
1109                         
1110                         if(newvalue != value)
1111                         {
1112                                 dstream<<"Changing value of \""<<name<<"\" = \""
1113                                                 <<value<<"\" -> \""<<newvalue<<"\""
1114                                                 <<std::endl;
1115                         }
1116
1117                         dst.push_back(name + " = " + newvalue + line_end);
1118
1119                         updated[name] = true;
1120                 }
1121                 
1122                 return true;
1123         }
1124
1125         /*
1126                 Updates configuration file
1127
1128                 Returns true on success
1129         */
1130         bool updateConfigFile(const char *filename)
1131         {
1132                 dstream<<"Updating configuration file: \""
1133                                 <<filename<<"\""<<std::endl;
1134                 
1135                 core::list<std::string> objects;
1136                 core::map<std::string, bool> updated;
1137                 
1138                 // Read and modify stuff
1139                 {
1140                         std::ifstream is(filename);
1141                         if(is.good() == false)
1142                         {
1143                                 dstream<<"INFO: updateConfigFile():"
1144                                                 " Error opening configuration file"
1145                                                 " for reading: \""
1146                                                 <<filename<<"\""<<std::endl;
1147                         }
1148                         else
1149                         {
1150                                 while(getUpdatedConfigObject(is, objects, updated));
1151                         }
1152                 }
1153                 
1154                 JMutexAutoLock lock(m_mutex);
1155                 
1156                 // Write stuff back
1157                 {
1158                         std::ofstream os(filename);
1159                         if(os.good() == false)
1160                         {
1161                                 dstream<<"Error opening configuration file"
1162                                                 " for writing: \""
1163                                                 <<filename<<"\""<<std::endl;
1164                                 return false;
1165                         }
1166                         
1167                         /*
1168                                 Write updated stuff
1169                         */
1170                         for(core::list<std::string>::Iterator
1171                                         i = objects.begin();
1172                                         i != objects.end(); i++)
1173                         {
1174                                 os<<(*i);
1175                         }
1176
1177                         /*
1178                                 Write stuff that was not already in the file
1179                         */
1180                         for(core::map<std::string, std::string>::Iterator
1181                                         i = m_settings.getIterator();
1182                                         i.atEnd() == false; i++)
1183                         {
1184                                 if(updated.find(i.getNode()->getKey()))
1185                                         continue;
1186                                 std::string name = i.getNode()->getKey();
1187                                 std::string value = i.getNode()->getValue();
1188                                 dstream<<"Adding \""<<name<<"\" = \""<<value<<"\""
1189                                                 <<std::endl;
1190                                 os<<name<<" = "<<value<<"\n";
1191                         }
1192                 }
1193                 
1194                 return true;
1195         }
1196
1197         /*
1198                 NOTE: Types of allowed_options are ignored
1199
1200                 returns true on success
1201         */
1202         bool parseCommandLine(int argc, char *argv[],
1203                         core::map<std::string, ValueSpec> &allowed_options)
1204         {
1205                 int i=1;
1206                 for(;;)
1207                 {
1208                         if(i >= argc)
1209                                 break;
1210                         std::string argname = argv[i];
1211                         if(argname.substr(0, 2) != "--")
1212                         {
1213                                 dstream<<"Invalid command-line parameter \""
1214                                                 <<argname<<"\": --<option> expected."<<std::endl;
1215                                 return false;
1216                         }
1217                         i++;
1218
1219                         std::string name = argname.substr(2);
1220
1221                         core::map<std::string, ValueSpec>::Node *n;
1222                         n = allowed_options.find(name);
1223                         if(n == NULL)
1224                         {
1225                                 dstream<<"Unknown command-line parameter \""
1226                                                 <<argname<<"\""<<std::endl;
1227                                 return false;
1228                         }
1229
1230                         ValueType type = n->getValue().type;
1231
1232                         std::string value = "";
1233                         
1234                         if(type == VALUETYPE_FLAG)
1235                         {
1236                                 value = "true";
1237                         }
1238                         else
1239                         {
1240                                 if(i >= argc)
1241                                 {
1242                                         dstream<<"Invalid command-line parameter \""
1243                                                         <<name<<"\": missing value"<<std::endl;
1244                                         return false;
1245                                 }
1246                                 value = argv[i];
1247                                 i++;
1248                         }
1249                         
1250
1251                         dstream<<"Valid command-line parameter: \""
1252                                         <<name<<"\" = \""<<value<<"\""
1253                                         <<std::endl;
1254                         set(name, value);
1255                 }
1256
1257                 return true;
1258         }
1259
1260         void set(std::string name, std::string value)
1261         {
1262                 JMutexAutoLock lock(m_mutex);
1263                 
1264                 m_settings[name] = value;
1265         }
1266
1267         void setDefault(std::string name, std::string value)
1268         {
1269                 JMutexAutoLock lock(m_mutex);
1270                 
1271                 m_defaults[name] = value;
1272         }
1273
1274         bool exists(std::string name)
1275         {
1276                 JMutexAutoLock lock(m_mutex);
1277                 
1278                 return (m_settings.find(name) || m_defaults.find(name));
1279         }
1280
1281         std::string get(std::string name)
1282         {
1283                 JMutexAutoLock lock(m_mutex);
1284                 
1285                 core::map<std::string, std::string>::Node *n;
1286                 n = m_settings.find(name);
1287                 if(n == NULL)
1288                 {
1289                         n = m_defaults.find(name);
1290                         if(n == NULL)
1291                         {
1292                                 dstream<<"INFO: Settings: Setting not found: \""
1293                                                 <<name<<"\""<<std::endl;
1294                                 throw SettingNotFoundException("Setting not found");
1295                         }
1296                 }
1297
1298                 return n->getValue();
1299         }
1300
1301         bool getBool(std::string name)
1302         {
1303                 return is_yes(get(name));
1304         }
1305         
1306         bool getFlag(std::string name)
1307         {
1308                 try
1309                 {
1310                         return getBool(name);
1311                 }
1312                 catch(SettingNotFoundException &e)
1313                 {
1314                         return false;
1315                 }
1316         }
1317
1318         // Asks if empty
1319         bool getBoolAsk(std::string name, std::string question, bool def)
1320         {
1321                 // If it is in settings
1322                 if(exists(name))
1323                         return getBool(name);
1324                 
1325                 std::string s;
1326                 char templine[10];
1327                 std::cout<<question<<" [y/N]: ";
1328                 std::cin.getline(templine, 10);
1329                 s = templine;
1330
1331                 if(s == "")
1332                         return def;
1333
1334                 return is_yes(s);
1335         }
1336
1337         float getFloat(std::string name)
1338         {
1339                 return stof(get(name));
1340         }
1341
1342         u16 getU16(std::string name)
1343         {
1344                 return stoi(get(name), 0, 65535);
1345         }
1346
1347         u16 getU16Ask(std::string name, std::string question, u16 def)
1348         {
1349                 // If it is in settings
1350                 if(exists(name))
1351                         return getU16(name);
1352                 
1353                 std::string s;
1354                 char templine[10];
1355                 std::cout<<question<<" ["<<def<<"]: ";
1356                 std::cin.getline(templine, 10);
1357                 s = templine;
1358
1359                 if(s == "")
1360                         return def;
1361
1362                 return stoi(s, 0, 65535);
1363         }
1364
1365         s16 getS16(std::string name)
1366         {
1367                 return stoi(get(name), -32768, 32767);
1368         }
1369
1370         s32 getS32(std::string name)
1371         {
1372                 return stoi(get(name));
1373         }
1374
1375         v3f getV3F(std::string name)
1376         {
1377                 v3f value;
1378                 Strfnd f(get(name));
1379                 f.next("(");
1380                 value.X = stof(f.next(","));
1381                 value.Y = stof(f.next(","));
1382                 value.Z = stof(f.next(")"));
1383                 return value;
1384         }
1385
1386         u64 getU64(std::string name)
1387         {
1388                 u64 value = 0;
1389                 std::string s = get(name);
1390                 std::istringstream ss(s);
1391                 ss>>value;
1392                 return value;
1393         }
1394
1395         void setBool(std::string name, bool value)
1396         {
1397                 if(value)
1398                         set(name, "true");
1399                 else
1400                         set(name, "false");
1401         }
1402
1403         void setS32(std::string name, s32 value)
1404         {
1405                 set(name, itos(value));
1406         }
1407
1408         void setFloat(std::string name, float value)
1409         {
1410                 set(name, ftos(value));
1411         }
1412
1413         void setV3F(std::string name, v3f value)
1414         {
1415                 std::ostringstream os;
1416                 os<<"("<<value.X<<","<<value.Y<<","<<value.Z<<")";
1417                 set(name, os.str());
1418         }
1419
1420         void setU64(std::string name, u64 value)
1421         {
1422                 std::ostringstream os;
1423                 os<<value;
1424                 set(name, os.str());
1425         }
1426
1427         void clear()
1428         {
1429                 JMutexAutoLock lock(m_mutex);
1430                 
1431                 m_settings.clear();
1432                 m_defaults.clear();
1433         }
1434
1435         Settings & operator+=(Settings &other)
1436         {
1437                 JMutexAutoLock lock(m_mutex);
1438                 JMutexAutoLock lock2(other.m_mutex);
1439                 
1440                 if(&other == this)
1441                         return *this;
1442
1443                 for(core::map<std::string, std::string>::Iterator
1444                                 i = other.m_settings.getIterator();
1445                                 i.atEnd() == false; i++)
1446                 {
1447                         m_settings.insert(i.getNode()->getKey(),
1448                                         i.getNode()->getValue());
1449                 }
1450                 
1451                 for(core::map<std::string, std::string>::Iterator
1452                                 i = other.m_defaults.getIterator();
1453                                 i.atEnd() == false; i++)
1454                 {
1455                         m_defaults.insert(i.getNode()->getKey(),
1456                                         i.getNode()->getValue());
1457                 }
1458
1459         }
1460
1461         Settings & operator=(Settings &other)
1462         {
1463                 JMutexAutoLock lock(m_mutex);
1464                 JMutexAutoLock lock2(other.m_mutex);
1465                 
1466                 if(&other == this)
1467                         return *this;
1468
1469                 clear();
1470                 (*this) += other;
1471                 
1472                 return *this;
1473         }
1474
1475 private:
1476         core::map<std::string, std::string> m_settings;
1477         core::map<std::string, std::string> m_defaults;
1478         // All methods that access m_settings/m_defaults directly should lock this.
1479         JMutex m_mutex;
1480 };
1481
1482 /*
1483         FIFO queue (well, actually a FILO also)
1484 */
1485 template<typename T>
1486 class Queue
1487 {
1488 public:
1489         void push_back(T t)
1490         {
1491                 m_list.push_back(t);
1492         }
1493         
1494         T pop_front()
1495         {
1496                 if(m_list.size() == 0)
1497                         throw ItemNotFoundException("Queue: queue is empty");
1498
1499                 typename core::list<T>::Iterator begin = m_list.begin();
1500                 T t = *begin;
1501                 m_list.erase(begin);
1502                 return t;
1503         }
1504         T pop_back()
1505         {
1506                 if(m_list.size() == 0)
1507                         throw ItemNotFoundException("Queue: queue is empty");
1508
1509                 typename core::list<T>::Iterator last = m_list.getLast();
1510                 T t = *last;
1511                 m_list.erase(last);
1512                 return t;
1513         }
1514
1515         u32 size()
1516         {
1517                 return m_list.size();
1518         }
1519
1520 protected:
1521         core::list<T> m_list;
1522 };
1523
1524 /*
1525         Thread-safe FIFO queue (well, actually a FILO also)
1526 */
1527
1528 template<typename T>
1529 class MutexedQueue
1530 {
1531 public:
1532         MutexedQueue()
1533         {
1534                 m_mutex.Init();
1535         }
1536         u32 size()
1537         {
1538                 JMutexAutoLock lock(m_mutex);
1539                 return m_list.size();
1540         }
1541         void push_back(T t)
1542         {
1543                 JMutexAutoLock lock(m_mutex);
1544                 m_list.push_back(t);
1545         }
1546         T pop_front(u32 wait_time_max_ms=0)
1547         {
1548                 u32 wait_time_ms = 0;
1549
1550                 for(;;)
1551                 {
1552                         {
1553                                 JMutexAutoLock lock(m_mutex);
1554
1555                                 if(m_list.size() > 0)
1556                                 {
1557                                         typename core::list<T>::Iterator begin = m_list.begin();
1558                                         T t = *begin;
1559                                         m_list.erase(begin);
1560                                         return t;
1561                                 }
1562
1563                                 if(wait_time_ms >= wait_time_max_ms)
1564                                         throw ItemNotFoundException("MutexedQueue: queue is empty");
1565                         }
1566
1567                         // Wait a while before trying again
1568                         sleep_ms(10);
1569                         wait_time_ms += 10;
1570                 }
1571         }
1572         T pop_back(u32 wait_time_max_ms=0)
1573         {
1574                 u32 wait_time_ms = 0;
1575
1576                 for(;;)
1577                 {
1578                         {
1579                                 JMutexAutoLock lock(m_mutex);
1580
1581                                 if(m_list.size() > 0)
1582                                 {
1583                                         typename core::list<T>::Iterator last = m_list.getLast();
1584                                         T t = *last;
1585                                         m_list.erase(last);
1586                                         return t;
1587                                 }
1588
1589                                 if(wait_time_ms >= wait_time_max_ms)
1590                                         throw ItemNotFoundException("MutexedQueue: queue is empty");
1591                         }
1592
1593                         // Wait a while before trying again
1594                         sleep_ms(10);
1595                         wait_time_ms += 10;
1596                 }
1597         }
1598
1599         JMutex & getMutex()
1600         {
1601                 return m_mutex;
1602         }
1603
1604         core::list<T> & getList()
1605         {
1606                 return m_list;
1607         }
1608
1609 protected:
1610         JMutex m_mutex;
1611         core::list<T> m_list;
1612 };
1613
1614 /*
1615         A single worker thread - multiple client threads queue framework.
1616 */
1617
1618 template<typename Caller, typename Data>
1619 class CallerInfo
1620 {
1621 public:
1622         Caller caller;
1623         Data data;
1624 };
1625
1626 template<typename Key, typename T, typename Caller, typename CallerData>
1627 class GetResult
1628 {
1629 public:
1630         Key key;
1631         T item;
1632         core::list<CallerInfo<Caller, CallerData> > callers;
1633 };
1634
1635 template<typename Key, typename T, typename Caller, typename CallerData>
1636 class ResultQueue: public MutexedQueue< GetResult<Key, T, Caller, CallerData> >
1637 {
1638 };
1639
1640 template<typename Key, typename T, typename Caller, typename CallerData>
1641 class GetRequest
1642 {
1643 public:
1644         GetRequest()
1645         {
1646                 dest = NULL;
1647         }
1648         GetRequest(ResultQueue<Key,T, Caller, CallerData> *a_dest)
1649         {
1650                 dest = a_dest;
1651         }
1652         GetRequest(ResultQueue<Key,T, Caller, CallerData> *a_dest,
1653                         Key a_key)
1654         {
1655                 dest = a_dest;
1656                 key = a_key;
1657         }
1658         ~GetRequest()
1659         {
1660         }
1661         
1662         Key key;
1663         ResultQueue<Key, T, Caller, CallerData> *dest;
1664         core::list<CallerInfo<Caller, CallerData> > callers;
1665 };
1666
1667 template<typename Key, typename T, typename Caller, typename CallerData>
1668 class RequestQueue
1669 {
1670 public:
1671         u32 size()
1672         {
1673                 return m_queue.size();
1674         }
1675
1676         void add(Key key, Caller caller, CallerData callerdata,
1677                         ResultQueue<Key, T, Caller, CallerData> *dest)
1678         {
1679                 JMutexAutoLock lock(m_queue.getMutex());
1680                 
1681                 /*
1682                         If the caller is already on the list, only update CallerData
1683                 */
1684                 for(typename core::list< GetRequest<Key, T, Caller, CallerData> >::Iterator
1685                                 i = m_queue.getList().begin();
1686                                 i != m_queue.getList().end(); i++)
1687                 {
1688                         GetRequest<Key, T, Caller, CallerData> &request = *i;
1689
1690                         if(request.key == key)
1691                         {
1692                                 for(typename core::list< CallerInfo<Caller, CallerData> >::Iterator
1693                                                 i = request.callers.begin();
1694                                                 i != request.callers.end(); i++)
1695                                 {
1696                                         CallerInfo<Caller, CallerData> &ca = *i;
1697                                         if(ca.caller == caller)
1698                                         {
1699                                                 ca.data = callerdata;
1700                                                 return;
1701                                         }
1702                                 }
1703                                 CallerInfo<Caller, CallerData> ca;
1704                                 ca.caller = caller;
1705                                 ca.data = callerdata;
1706                                 request.callers.push_back(ca);
1707                                 return;
1708                         }
1709                 }
1710
1711                 /*
1712                         Else add a new request to the queue
1713                 */
1714
1715                 GetRequest<Key, T, Caller, CallerData> request;
1716                 request.key = key;
1717                 CallerInfo<Caller, CallerData> ca;
1718                 ca.caller = caller;
1719                 ca.data = callerdata;
1720                 request.callers.push_back(ca);
1721                 request.dest = dest;
1722                 
1723                 m_queue.getList().push_back(request);
1724         }
1725
1726         GetRequest<Key, T, Caller, CallerData> pop(bool wait_if_empty=false)
1727         {
1728                 return m_queue.pop_front(wait_if_empty);
1729         }
1730
1731 private:
1732         MutexedQueue< GetRequest<Key, T, Caller, CallerData> > m_queue;
1733 };
1734
1735 /*
1736         Pseudo-random (VC++ rand() sucks)
1737 */
1738 int myrand(void);
1739 void mysrand(unsigned seed);
1740 #define MYRAND_MAX 32767
1741
1742 inline int myrand_range(int min, int max)
1743 {
1744         if(max-min > MYRAND_MAX)
1745         {
1746                 dstream<<"WARNING: myrand_range: max-min > MYRAND_MAX"<<std::endl;
1747                 assert(0);
1748         }
1749         if(min > max)
1750         {
1751                 assert(0);
1752                 return max;
1753         }
1754         return (myrand()%(max-min+1))+min;
1755 }
1756
1757 /*
1758         Miscellaneous functions
1759 */
1760
1761 bool isBlockInSight(v3s16 blockpos_b, v3f camera_pos, v3f camera_dir, f32 range,
1762                 f32 *distance_ptr=NULL);
1763
1764 /*
1765         Queue with unique values with fast checking of value existence
1766 */
1767
1768 template<typename Value>
1769 class UniqueQueue
1770 {
1771 public:
1772         
1773         /*
1774                 Does nothing if value is already queued.
1775                 Return value:
1776                         true: value added
1777                         false: value already exists
1778         */
1779         bool push_back(Value value)
1780         {
1781                 // Check if already exists
1782                 if(m_map.find(value) != NULL)
1783                         return false;
1784
1785                 // Add
1786                 m_map.insert(value, 0);
1787                 m_list.push_back(value);
1788                 
1789                 return true;
1790         }
1791
1792         Value pop_front()
1793         {
1794                 typename core::list<Value>::Iterator i = m_list.begin();
1795                 Value value = *i;
1796                 m_map.remove(value);
1797                 m_list.erase(i);
1798                 return value;
1799         }
1800
1801         u32 size()
1802         {
1803                 assert(m_list.size() == m_map.size());
1804                 return m_list.size();
1805         }
1806
1807 private:
1808         core::map<Value, u8> m_map;
1809         core::list<Value> m_list;
1810 };
1811
1812 #if 1
1813 template<typename Key, typename Value>
1814 class MutexedMap
1815 {
1816 public:
1817         MutexedMap()
1818         {
1819                 m_mutex.Init();
1820                 assert(m_mutex.IsInitialized());
1821         }
1822         
1823         void set(const Key &name, const Value &value)
1824         {
1825                 JMutexAutoLock lock(m_mutex);
1826
1827                 m_values[name] = value;
1828         }
1829         
1830         bool get(const Key &name, Value *result)
1831         {
1832                 JMutexAutoLock lock(m_mutex);
1833
1834                 typename core::map<Key, Value>::Node *n;
1835                 n = m_values.find(name);
1836
1837                 if(n == NULL)
1838                         return false;
1839                 
1840                 if(result != NULL)
1841                         *result = n->getValue();
1842                         
1843                 return true;
1844         }
1845
1846 private:
1847         core::map<Key, Value> m_values;
1848         JMutex m_mutex;
1849 };
1850 #endif
1851
1852 /*
1853         Generates ids for comparable values.
1854         Id=0 is reserved for "no value".
1855
1856         Is fast at:
1857         - Returning value by id (very fast)
1858         - Returning id by value
1859         - Generating a new id for a value
1860
1861         Is not able to:
1862         - Remove an id/value pair (is possible to implement but slow)
1863 */
1864 template<typename T>
1865 class MutexedIdGenerator
1866 {
1867 public:
1868         MutexedIdGenerator()
1869         {
1870                 m_mutex.Init();
1871                 assert(m_mutex.IsInitialized());
1872         }
1873         
1874         // Returns true if found
1875         bool getValue(u32 id, T &value)
1876         {
1877                 if(id == 0)
1878                         return false;
1879                 JMutexAutoLock lock(m_mutex);
1880                 if(m_id_to_value.size() < id)
1881                         return false;
1882                 value = m_id_to_value[id-1];
1883                 return true;
1884         }
1885         
1886         // If id exists for value, returns the id.
1887         // Otherwise generates an id for the value.
1888         u32 getId(const T &value)
1889         {
1890                 JMutexAutoLock lock(m_mutex);
1891                 typename core::map<T, u32>::Node *n;
1892                 n = m_value_to_id.find(value);
1893                 if(n != NULL)
1894                         return n->getValue();
1895                 m_id_to_value.push_back(value);
1896                 u32 new_id = m_id_to_value.size();
1897                 m_value_to_id.insert(value, new_id);
1898                 return new_id;
1899         }
1900
1901 private:
1902         JMutex m_mutex;
1903         // Values are stored here at id-1 position (id 1 = [0])
1904         core::array<T> m_id_to_value;
1905         core::map<T, u32> m_value_to_id;
1906 };
1907
1908 /*
1909         Checks if a string contains only supplied characters
1910 */
1911 inline bool string_allowed(const std::string &s, const std::string &allowed_chars)
1912 {
1913         for(u32 i=0; i<s.size(); i++)
1914         {
1915                 bool confirmed = false;
1916                 for(u32 j=0; j<allowed_chars.size(); j++)
1917                 {
1918                         if(s[i] == allowed_chars[j])
1919                         {
1920                                 confirmed = true;
1921                                 break;
1922                         }
1923                 }
1924                 if(confirmed == false)
1925                         return false;
1926         }
1927         return true;
1928 }
1929
1930 /*
1931         Forcefully wraps string into rows using \n
1932         (no word wrap, used for showing paths in gui)
1933 */
1934 inline std::string wrap_rows(const std::string &from, u32 rowlen)
1935 {
1936         std::string to;
1937         for(u32 i=0; i<from.size(); i++)
1938         {
1939                 if(i != 0 && i%rowlen == 0)
1940                         to += '\n';
1941                 to += from[i];
1942         }
1943         return to;
1944 }
1945
1946 /*
1947         Some helper stuff
1948 */
1949 #define MYMIN(a,b) ((a)<(b)?(a):(b))
1950 #define MYMAX(a,b) ((a)>(b)?(a):(b))
1951
1952 /*
1953         Returns integer position of node in given floating point position
1954 */
1955 inline v3s16 floatToInt(v3f p, f32 d)
1956 {
1957         v3s16 p2(
1958                 (p.X + (p.X>0 ? d/2 : -d/2))/d,
1959                 (p.Y + (p.Y>0 ? d/2 : -d/2))/d,
1960                 (p.Z + (p.Z>0 ? d/2 : -d/2))/d);
1961         return p2;
1962 }
1963
1964 /*
1965         Returns floating point position of node in given integer position
1966 */
1967 inline v3f intToFloat(v3s16 p, f32 d)
1968 {
1969         v3f p2(
1970                 (f32)p.X * d,
1971                 (f32)p.Y * d,
1972                 (f32)p.Z * d
1973         );
1974         return p2;
1975 }
1976
1977 /*
1978         More serialization stuff
1979 */
1980
1981 // Creates a string with the length as the first two bytes
1982 inline std::string serializeString(const std::string &plain)
1983 {
1984         //assert(plain.size() <= 65535);
1985         if(plain.size() > 65535)
1986                 throw SerializationError("String too long for serializeString");
1987         char buf[2];
1988         writeU16((u8*)&buf[0], plain.size());
1989         std::string s;
1990         s.append(buf, 2);
1991         s.append(plain);
1992         return s;
1993 }
1994
1995 // Creates a string with the length as the first two bytes from wide string
1996 inline std::string serializeWideString(const std::wstring &plain)
1997 {
1998         //assert(plain.size() <= 65535);
1999         if(plain.size() > 65535)
2000                 throw SerializationError("String too long for serializeString");
2001         char buf[2];
2002         writeU16((u8*)buf, plain.size());
2003         std::string s;
2004         s.append(buf, 2);
2005         for(u32 i=0; i<plain.size(); i++)
2006         {
2007                 writeU16((u8*)buf, plain[i]);
2008                 s.append(buf, 2);
2009         }
2010         return s;
2011 }
2012
2013 // Reads a string with the length as the first two bytes
2014 inline std::string deSerializeString(std::istream &is)
2015 {
2016         char buf[2];
2017         is.read(buf, 2);
2018         if(is.gcount() != 2)
2019                 throw SerializationError("deSerializeString: size not read");
2020         u16 s_size = readU16((u8*)buf);
2021         if(s_size == 0)
2022                 return "";
2023         Buffer<char> buf2(s_size);
2024         is.read(&buf2[0], s_size);
2025         std::string s;
2026         s.reserve(s_size);
2027         s.append(&buf2[0], s_size);
2028         return s;
2029 }
2030
2031 // Reads a wide string with the length as the first two bytes
2032 inline std::wstring deSerializeWideString(std::istream &is)
2033 {
2034         char buf[2];
2035         is.read(buf, 2);
2036         if(is.gcount() != 2)
2037                 throw SerializationError("deSerializeString: size not read");
2038         u16 s_size = readU16((u8*)buf);
2039         if(s_size == 0)
2040                 return L"";
2041         std::wstring s;
2042         s.reserve(s_size);
2043         for(u32 i=0; i<s_size; i++)
2044         {
2045                 is.read(&buf[0], 2);
2046                 wchar_t c16 = readU16((u8*)buf);
2047                 s.append(&c16, 1);
2048         }
2049         return s;
2050 }
2051
2052 // Creates a string with the length as the first four bytes
2053 inline std::string serializeLongString(const std::string &plain)
2054 {
2055         char buf[4];
2056         writeU32((u8*)&buf[0], plain.size());
2057         std::string s;
2058         s.append(buf, 4);
2059         s.append(plain);
2060         return s;
2061 }
2062
2063 // Reads a string with the length as the first four bytes
2064 inline std::string deSerializeLongString(std::istream &is)
2065 {
2066         char buf[4];
2067         is.read(buf, 4);
2068         if(is.gcount() != 4)
2069                 throw SerializationError("deSerializeLongString: size not read");
2070         u32 s_size = readU32((u8*)buf);
2071         if(s_size == 0)
2072                 return "";
2073         Buffer<char> buf2(s_size);
2074         is.read(&buf2[0], s_size);
2075         std::string s;
2076         s.reserve(s_size);
2077         s.append(&buf2[0], s_size);
2078         return s;
2079 }
2080
2081 //
2082
2083 inline u32 time_to_daynight_ratio(u32 time_of_day)
2084 {
2085         const s32 daylength = 16;
2086         const s32 nightlength = 6;
2087         const s32 daytimelength = 8;
2088         s32 d = daylength;
2089         s32 t = (((time_of_day)%24000)/(24000/d));
2090         if(t < nightlength/2 || t >= d - nightlength/2)
2091                 //return 300;
2092                 return 350;
2093         else if(t >= d/2 - daytimelength/2 && t < d/2 + daytimelength/2)
2094                 return 1000;
2095         else
2096                 return 750;
2097 }
2098
2099 // Random helper. Usually d=BS
2100 inline core::aabbox3d<f32> getNodeBox(v3s16 p, float d)
2101 {
2102         return core::aabbox3d<f32>(
2103                 (float)p.X * d - 0.5*d,
2104                 (float)p.Y * d - 0.5*d,
2105                 (float)p.Z * d - 0.5*d,
2106                 (float)p.X * d + 0.5*d,
2107                 (float)p.Y * d + 0.5*d,
2108                 (float)p.Z * d + 0.5*d
2109         );
2110 }
2111         
2112 class IntervalLimiter
2113 {
2114 public:
2115         IntervalLimiter():
2116                 m_accumulator(0)
2117         {
2118         }
2119         /*
2120                 dtime: time from last call to this method
2121                 wanted_interval: interval wanted
2122                 return value:
2123                         true: action should be skipped
2124                         false: action should be done
2125         */
2126         bool step(float dtime, float wanted_interval)
2127         {
2128                 m_accumulator += dtime;
2129                 if(m_accumulator < wanted_interval)
2130                         return false;
2131                 m_accumulator -= wanted_interval;
2132                 return true;
2133         }
2134 protected:
2135         float m_accumulator;
2136 };
2137
2138 std::string translatePassword(std::string playername, std::wstring password);
2139
2140 #endif
2141