Server should use the same eye position as the client
[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                 return *this;
1460
1461         }
1462
1463         Settings & operator=(Settings &other)
1464         {
1465                 JMutexAutoLock lock(m_mutex);
1466                 JMutexAutoLock lock2(other.m_mutex);
1467                 
1468                 if(&other == this)
1469                         return *this;
1470
1471                 clear();
1472                 (*this) += other;
1473                 
1474                 return *this;
1475         }
1476
1477 private:
1478         core::map<std::string, std::string> m_settings;
1479         core::map<std::string, std::string> m_defaults;
1480         // All methods that access m_settings/m_defaults directly should lock this.
1481         JMutex m_mutex;
1482 };
1483
1484 /*
1485         FIFO queue (well, actually a FILO also)
1486 */
1487 template<typename T>
1488 class Queue
1489 {
1490 public:
1491         void push_back(T t)
1492         {
1493                 m_list.push_back(t);
1494         }
1495         
1496         T pop_front()
1497         {
1498                 if(m_list.size() == 0)
1499                         throw ItemNotFoundException("Queue: queue is empty");
1500
1501                 typename core::list<T>::Iterator begin = m_list.begin();
1502                 T t = *begin;
1503                 m_list.erase(begin);
1504                 return t;
1505         }
1506         T pop_back()
1507         {
1508                 if(m_list.size() == 0)
1509                         throw ItemNotFoundException("Queue: queue is empty");
1510
1511                 typename core::list<T>::Iterator last = m_list.getLast();
1512                 T t = *last;
1513                 m_list.erase(last);
1514                 return t;
1515         }
1516
1517         u32 size()
1518         {
1519                 return m_list.size();
1520         }
1521
1522 protected:
1523         core::list<T> m_list;
1524 };
1525
1526 /*
1527         Thread-safe FIFO queue (well, actually a FILO also)
1528 */
1529
1530 template<typename T>
1531 class MutexedQueue
1532 {
1533 public:
1534         MutexedQueue()
1535         {
1536                 m_mutex.Init();
1537         }
1538         u32 size()
1539         {
1540                 JMutexAutoLock lock(m_mutex);
1541                 return m_list.size();
1542         }
1543         void push_back(T t)
1544         {
1545                 JMutexAutoLock lock(m_mutex);
1546                 m_list.push_back(t);
1547         }
1548         T pop_front(u32 wait_time_max_ms=0)
1549         {
1550                 u32 wait_time_ms = 0;
1551
1552                 for(;;)
1553                 {
1554                         {
1555                                 JMutexAutoLock lock(m_mutex);
1556
1557                                 if(m_list.size() > 0)
1558                                 {
1559                                         typename core::list<T>::Iterator begin = m_list.begin();
1560                                         T t = *begin;
1561                                         m_list.erase(begin);
1562                                         return t;
1563                                 }
1564
1565                                 if(wait_time_ms >= wait_time_max_ms)
1566                                         throw ItemNotFoundException("MutexedQueue: queue is empty");
1567                         }
1568
1569                         // Wait a while before trying again
1570                         sleep_ms(10);
1571                         wait_time_ms += 10;
1572                 }
1573         }
1574         T pop_back(u32 wait_time_max_ms=0)
1575         {
1576                 u32 wait_time_ms = 0;
1577
1578                 for(;;)
1579                 {
1580                         {
1581                                 JMutexAutoLock lock(m_mutex);
1582
1583                                 if(m_list.size() > 0)
1584                                 {
1585                                         typename core::list<T>::Iterator last = m_list.getLast();
1586                                         T t = *last;
1587                                         m_list.erase(last);
1588                                         return t;
1589                                 }
1590
1591                                 if(wait_time_ms >= wait_time_max_ms)
1592                                         throw ItemNotFoundException("MutexedQueue: queue is empty");
1593                         }
1594
1595                         // Wait a while before trying again
1596                         sleep_ms(10);
1597                         wait_time_ms += 10;
1598                 }
1599         }
1600
1601         JMutex & getMutex()
1602         {
1603                 return m_mutex;
1604         }
1605
1606         core::list<T> & getList()
1607         {
1608                 return m_list;
1609         }
1610
1611 protected:
1612         JMutex m_mutex;
1613         core::list<T> m_list;
1614 };
1615
1616 /*
1617         A single worker thread - multiple client threads queue framework.
1618 */
1619
1620 template<typename Caller, typename Data>
1621 class CallerInfo
1622 {
1623 public:
1624         Caller caller;
1625         Data data;
1626 };
1627
1628 template<typename Key, typename T, typename Caller, typename CallerData>
1629 class GetResult
1630 {
1631 public:
1632         Key key;
1633         T item;
1634         core::list<CallerInfo<Caller, CallerData> > callers;
1635 };
1636
1637 template<typename Key, typename T, typename Caller, typename CallerData>
1638 class ResultQueue: public MutexedQueue< GetResult<Key, T, Caller, CallerData> >
1639 {
1640 };
1641
1642 template<typename Key, typename T, typename Caller, typename CallerData>
1643 class GetRequest
1644 {
1645 public:
1646         GetRequest()
1647         {
1648                 dest = NULL;
1649         }
1650         GetRequest(ResultQueue<Key,T, Caller, CallerData> *a_dest)
1651         {
1652                 dest = a_dest;
1653         }
1654         GetRequest(ResultQueue<Key,T, Caller, CallerData> *a_dest,
1655                         Key a_key)
1656         {
1657                 dest = a_dest;
1658                 key = a_key;
1659         }
1660         ~GetRequest()
1661         {
1662         }
1663         
1664         Key key;
1665         ResultQueue<Key, T, Caller, CallerData> *dest;
1666         core::list<CallerInfo<Caller, CallerData> > callers;
1667 };
1668
1669 template<typename Key, typename T, typename Caller, typename CallerData>
1670 class RequestQueue
1671 {
1672 public:
1673         u32 size()
1674         {
1675                 return m_queue.size();
1676         }
1677
1678         void add(Key key, Caller caller, CallerData callerdata,
1679                         ResultQueue<Key, T, Caller, CallerData> *dest)
1680         {
1681                 JMutexAutoLock lock(m_queue.getMutex());
1682                 
1683                 /*
1684                         If the caller is already on the list, only update CallerData
1685                 */
1686                 for(typename core::list< GetRequest<Key, T, Caller, CallerData> >::Iterator
1687                                 i = m_queue.getList().begin();
1688                                 i != m_queue.getList().end(); i++)
1689                 {
1690                         GetRequest<Key, T, Caller, CallerData> &request = *i;
1691
1692                         if(request.key == key)
1693                         {
1694                                 for(typename core::list< CallerInfo<Caller, CallerData> >::Iterator
1695                                                 i = request.callers.begin();
1696                                                 i != request.callers.end(); i++)
1697                                 {
1698                                         CallerInfo<Caller, CallerData> &ca = *i;
1699                                         if(ca.caller == caller)
1700                                         {
1701                                                 ca.data = callerdata;
1702                                                 return;
1703                                         }
1704                                 }
1705                                 CallerInfo<Caller, CallerData> ca;
1706                                 ca.caller = caller;
1707                                 ca.data = callerdata;
1708                                 request.callers.push_back(ca);
1709                                 return;
1710                         }
1711                 }
1712
1713                 /*
1714                         Else add a new request to the queue
1715                 */
1716
1717                 GetRequest<Key, T, Caller, CallerData> request;
1718                 request.key = key;
1719                 CallerInfo<Caller, CallerData> ca;
1720                 ca.caller = caller;
1721                 ca.data = callerdata;
1722                 request.callers.push_back(ca);
1723                 request.dest = dest;
1724                 
1725                 m_queue.getList().push_back(request);
1726         }
1727
1728         GetRequest<Key, T, Caller, CallerData> pop(bool wait_if_empty=false)
1729         {
1730                 return m_queue.pop_front(wait_if_empty);
1731         }
1732
1733 private:
1734         MutexedQueue< GetRequest<Key, T, Caller, CallerData> > m_queue;
1735 };
1736
1737 /*
1738         Pseudo-random (VC++ rand() sucks)
1739 */
1740 int myrand(void);
1741 void mysrand(unsigned seed);
1742 #define MYRAND_MAX 32767
1743
1744 inline int myrand_range(int min, int max)
1745 {
1746         if(max-min > MYRAND_MAX)
1747         {
1748                 dstream<<"WARNING: myrand_range: max-min > MYRAND_MAX"<<std::endl;
1749                 assert(0);
1750         }
1751         if(min > max)
1752         {
1753                 assert(0);
1754                 return max;
1755         }
1756         return (myrand()%(max-min+1))+min;
1757 }
1758
1759 /*
1760         Miscellaneous functions
1761 */
1762
1763 bool isBlockInSight(v3s16 blockpos_b, v3f camera_pos, v3f camera_dir, f32 range,
1764                 f32 *distance_ptr=NULL);
1765
1766 /*
1767         Queue with unique values with fast checking of value existence
1768 */
1769
1770 template<typename Value>
1771 class UniqueQueue
1772 {
1773 public:
1774         
1775         /*
1776                 Does nothing if value is already queued.
1777                 Return value:
1778                         true: value added
1779                         false: value already exists
1780         */
1781         bool push_back(Value value)
1782         {
1783                 // Check if already exists
1784                 if(m_map.find(value) != NULL)
1785                         return false;
1786
1787                 // Add
1788                 m_map.insert(value, 0);
1789                 m_list.push_back(value);
1790                 
1791                 return true;
1792         }
1793
1794         Value pop_front()
1795         {
1796                 typename core::list<Value>::Iterator i = m_list.begin();
1797                 Value value = *i;
1798                 m_map.remove(value);
1799                 m_list.erase(i);
1800                 return value;
1801         }
1802
1803         u32 size()
1804         {
1805                 assert(m_list.size() == m_map.size());
1806                 return m_list.size();
1807         }
1808
1809 private:
1810         core::map<Value, u8> m_map;
1811         core::list<Value> m_list;
1812 };
1813
1814 #if 1
1815 template<typename Key, typename Value>
1816 class MutexedMap
1817 {
1818 public:
1819         MutexedMap()
1820         {
1821                 m_mutex.Init();
1822                 assert(m_mutex.IsInitialized());
1823         }
1824         
1825         void set(const Key &name, const Value &value)
1826         {
1827                 JMutexAutoLock lock(m_mutex);
1828
1829                 m_values[name] = value;
1830         }
1831         
1832         bool get(const Key &name, Value *result)
1833         {
1834                 JMutexAutoLock lock(m_mutex);
1835
1836                 typename core::map<Key, Value>::Node *n;
1837                 n = m_values.find(name);
1838
1839                 if(n == NULL)
1840                         return false;
1841                 
1842                 if(result != NULL)
1843                         *result = n->getValue();
1844                         
1845                 return true;
1846         }
1847
1848 private:
1849         core::map<Key, Value> m_values;
1850         JMutex m_mutex;
1851 };
1852 #endif
1853
1854 /*
1855         Generates ids for comparable values.
1856         Id=0 is reserved for "no value".
1857
1858         Is fast at:
1859         - Returning value by id (very fast)
1860         - Returning id by value
1861         - Generating a new id for a value
1862
1863         Is not able to:
1864         - Remove an id/value pair (is possible to implement but slow)
1865 */
1866 template<typename T>
1867 class MutexedIdGenerator
1868 {
1869 public:
1870         MutexedIdGenerator()
1871         {
1872                 m_mutex.Init();
1873                 assert(m_mutex.IsInitialized());
1874         }
1875         
1876         // Returns true if found
1877         bool getValue(u32 id, T &value)
1878         {
1879                 if(id == 0)
1880                         return false;
1881                 JMutexAutoLock lock(m_mutex);
1882                 if(m_id_to_value.size() < id)
1883                         return false;
1884                 value = m_id_to_value[id-1];
1885                 return true;
1886         }
1887         
1888         // If id exists for value, returns the id.
1889         // Otherwise generates an id for the value.
1890         u32 getId(const T &value)
1891         {
1892                 JMutexAutoLock lock(m_mutex);
1893                 typename core::map<T, u32>::Node *n;
1894                 n = m_value_to_id.find(value);
1895                 if(n != NULL)
1896                         return n->getValue();
1897                 m_id_to_value.push_back(value);
1898                 u32 new_id = m_id_to_value.size();
1899                 m_value_to_id.insert(value, new_id);
1900                 return new_id;
1901         }
1902
1903 private:
1904         JMutex m_mutex;
1905         // Values are stored here at id-1 position (id 1 = [0])
1906         core::array<T> m_id_to_value;
1907         core::map<T, u32> m_value_to_id;
1908 };
1909
1910 /*
1911         Checks if a string contains only supplied characters
1912 */
1913 inline bool string_allowed(const std::string &s, const std::string &allowed_chars)
1914 {
1915         for(u32 i=0; i<s.size(); i++)
1916         {
1917                 bool confirmed = false;
1918                 for(u32 j=0; j<allowed_chars.size(); j++)
1919                 {
1920                         if(s[i] == allowed_chars[j])
1921                         {
1922                                 confirmed = true;
1923                                 break;
1924                         }
1925                 }
1926                 if(confirmed == false)
1927                         return false;
1928         }
1929         return true;
1930 }
1931
1932 /*
1933         Forcefully wraps string into rows using \n
1934         (no word wrap, used for showing paths in gui)
1935 */
1936 inline std::string wrap_rows(const std::string &from, u32 rowlen)
1937 {
1938         std::string to;
1939         for(u32 i=0; i<from.size(); i++)
1940         {
1941                 if(i != 0 && i%rowlen == 0)
1942                         to += '\n';
1943                 to += from[i];
1944         }
1945         return to;
1946 }
1947
1948 /*
1949         Some helper stuff
1950 */
1951 #define MYMIN(a,b) ((a)<(b)?(a):(b))
1952 #define MYMAX(a,b) ((a)>(b)?(a):(b))
1953
1954 /*
1955         Returns integer position of node in given floating point position
1956 */
1957 inline v3s16 floatToInt(v3f p, f32 d)
1958 {
1959         v3s16 p2(
1960                 (p.X + (p.X>0 ? d/2 : -d/2))/d,
1961                 (p.Y + (p.Y>0 ? d/2 : -d/2))/d,
1962                 (p.Z + (p.Z>0 ? d/2 : -d/2))/d);
1963         return p2;
1964 }
1965
1966 /*
1967         Returns floating point position of node in given integer position
1968 */
1969 inline v3f intToFloat(v3s16 p, f32 d)
1970 {
1971         v3f p2(
1972                 (f32)p.X * d,
1973                 (f32)p.Y * d,
1974                 (f32)p.Z * d
1975         );
1976         return p2;
1977 }
1978
1979 /*
1980         More serialization stuff
1981 */
1982
1983 // Creates a string with the length as the first two bytes
1984 inline std::string serializeString(const std::string &plain)
1985 {
1986         //assert(plain.size() <= 65535);
1987         if(plain.size() > 65535)
1988                 throw SerializationError("String too long for serializeString");
1989         char buf[2];
1990         writeU16((u8*)&buf[0], plain.size());
1991         std::string s;
1992         s.append(buf, 2);
1993         s.append(plain);
1994         return s;
1995 }
1996
1997 // Creates a string with the length as the first two bytes from wide string
1998 inline std::string serializeWideString(const std::wstring &plain)
1999 {
2000         //assert(plain.size() <= 65535);
2001         if(plain.size() > 65535)
2002                 throw SerializationError("String too long for serializeString");
2003         char buf[2];
2004         writeU16((u8*)buf, plain.size());
2005         std::string s;
2006         s.append(buf, 2);
2007         for(u32 i=0; i<plain.size(); i++)
2008         {
2009                 writeU16((u8*)buf, plain[i]);
2010                 s.append(buf, 2);
2011         }
2012         return s;
2013 }
2014
2015 // Reads a string with the length as the first two bytes
2016 inline std::string deSerializeString(std::istream &is)
2017 {
2018         char buf[2];
2019         is.read(buf, 2);
2020         if(is.gcount() != 2)
2021                 throw SerializationError("deSerializeString: size not read");
2022         u16 s_size = readU16((u8*)buf);
2023         if(s_size == 0)
2024                 return "";
2025         Buffer<char> buf2(s_size);
2026         is.read(&buf2[0], s_size);
2027         std::string s;
2028         s.reserve(s_size);
2029         s.append(&buf2[0], s_size);
2030         return s;
2031 }
2032
2033 // Reads a wide string with the length as the first two bytes
2034 inline std::wstring deSerializeWideString(std::istream &is)
2035 {
2036         char buf[2];
2037         is.read(buf, 2);
2038         if(is.gcount() != 2)
2039                 throw SerializationError("deSerializeString: size not read");
2040         u16 s_size = readU16((u8*)buf);
2041         if(s_size == 0)
2042                 return L"";
2043         std::wstring s;
2044         s.reserve(s_size);
2045         for(u32 i=0; i<s_size; i++)
2046         {
2047                 is.read(&buf[0], 2);
2048                 wchar_t c16 = readU16((u8*)buf);
2049                 s.append(&c16, 1);
2050         }
2051         return s;
2052 }
2053
2054 // Creates a string with the length as the first four bytes
2055 inline std::string serializeLongString(const std::string &plain)
2056 {
2057         char buf[4];
2058         writeU32((u8*)&buf[0], plain.size());
2059         std::string s;
2060         s.append(buf, 4);
2061         s.append(plain);
2062         return s;
2063 }
2064
2065 // Reads a string with the length as the first four bytes
2066 inline std::string deSerializeLongString(std::istream &is)
2067 {
2068         char buf[4];
2069         is.read(buf, 4);
2070         if(is.gcount() != 4)
2071                 throw SerializationError("deSerializeLongString: size not read");
2072         u32 s_size = readU32((u8*)buf);
2073         if(s_size == 0)
2074                 return "";
2075         Buffer<char> buf2(s_size);
2076         is.read(&buf2[0], s_size);
2077         std::string s;
2078         s.reserve(s_size);
2079         s.append(&buf2[0], s_size);
2080         return s;
2081 }
2082
2083 //
2084
2085 inline u32 time_to_daynight_ratio(u32 time_of_day)
2086 {
2087         const s32 daylength = 16;
2088         const s32 nightlength = 6;
2089         const s32 daytimelength = 8;
2090         s32 d = daylength;
2091         s32 t = (((time_of_day)%24000)/(24000/d));
2092         if(t < nightlength/2 || t >= d - nightlength/2)
2093                 //return 300;
2094                 return 350;
2095         else if(t >= d/2 - daytimelength/2 && t < d/2 + daytimelength/2)
2096                 return 1000;
2097         else
2098                 return 750;
2099 }
2100
2101 // Random helper. Usually d=BS
2102 inline core::aabbox3d<f32> getNodeBox(v3s16 p, float d)
2103 {
2104         return core::aabbox3d<f32>(
2105                 (float)p.X * d - 0.5*d,
2106                 (float)p.Y * d - 0.5*d,
2107                 (float)p.Z * d - 0.5*d,
2108                 (float)p.X * d + 0.5*d,
2109                 (float)p.Y * d + 0.5*d,
2110                 (float)p.Z * d + 0.5*d
2111         );
2112 }
2113         
2114 class IntervalLimiter
2115 {
2116 public:
2117         IntervalLimiter():
2118                 m_accumulator(0)
2119         {
2120         }
2121         /*
2122                 dtime: time from last call to this method
2123                 wanted_interval: interval wanted
2124                 return value:
2125                         true: action should be skipped
2126                         false: action should be done
2127         */
2128         bool step(float dtime, float wanted_interval)
2129         {
2130                 m_accumulator += dtime;
2131                 if(m_accumulator < wanted_interval)
2132                         return false;
2133                 m_accumulator -= wanted_interval;
2134                 return true;
2135         }
2136 protected:
2137         float m_accumulator;
2138 };
2139
2140 std::string translatePassword(std::string playername, std::wstring password);
2141
2142 #endif
2143