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