Subversion Repository Public Repository

fonline_sdk

This repository has no backups
This repository's network speed is throttled to 100KB/sec

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
// FOS Server Client
// Data serialization

shared class Serializator
{
    private      uint8[] dataArray;
    private uint curPos;
    private uint bufSize;
    private uint dataSize;

    Serializator()
    {
        curPos = 0;
        bufSize = 0;
        dataSize = 0;
    }

    Serializator( uint approxSize )
    {
        curPos = 0;
        bufSize = 0;
        dataSize = 0;
        GrowBuffer( approxSize );
    }

    void GrowBuffer( uint size )
    {
        if( size <= bufSize )
            return;
        if( bufSize == 0 )
            bufSize = 1;
        while( size > bufSize )
            bufSize *= 2;
        dataArray.resize( bufSize );
    }

    #ifdef __CLIENT
    void SaveToCache( string& name )
    {
        SetCacheData( name, dataArray, dataSize );
        Clear();
    }

    uint LoadFromCache( string& name )
    {
        Clear();
        if( GetCacheData( name, dataArray ) )
        {
            bufSize = dataArray.length();
            dataSize = bufSize;
        }
        return bufSize;
    }
    #endif

    uint8[] GetData()
    {
        uint8[] data = dataArray;
        data.resize( dataSize );
        return data;
    }

    uint SetData( const uint8[]& data )
    {
        dataArray = data;
        bufSize = data.length();
        dataSize = data.length();
        return dataSize;
    }

    void Clear()
    {
        curPos = 0;
        bufSize = 0;
        dataSize = 0;
    }

    Serializator& SetcurPos( uint pos )
    {
        GrowBuffer( pos );
        curPos = pos;
        if( curPos > dataSize )
            dataSize = curPos;
        return this;
    }

    Serializator& Fill( uint8 value, uint length )
    {
        GrowBuffer( curPos + length );
        for( uint i = 0; i < length; i++ )
            dataArray[ curPos++ ] = value;
        if( curPos > dataSize )
            dataSize = curPos;
        return this;
    }

    Serializator& Set( const int64& value )
    {
        GrowBuffer( curPos + 8 );
        dataArray[ curPos++ ] = ( value >> 56 ) & 0xFF;
        dataArray[ curPos++ ] = ( value >> 48 ) & 0xFF;
        dataArray[ curPos++ ] = ( value >> 40 ) & 0xFF;
        dataArray[ curPos++ ] = ( value >> 32 ) & 0xFF;
        dataArray[ curPos++ ] = ( value >> 24 ) & 0xFF;
        dataArray[ curPos++ ] = ( value >> 16 ) & 0xFF;
        dataArray[ curPos++ ] = ( value >> 8 ) & 0xFF;
        dataArray[ curPos++ ] = value & 0xFF;
        if( curPos > dataSize )
            dataSize = curPos;
        return this;
    }

    Serializator& Set( const int32& value )
    {
        GrowBuffer( curPos + 4 );
        dataArray[ curPos++ ] = ( value >> 24 ) & 0xFF;
        dataArray[ curPos++ ] = ( value >> 16 ) & 0xFF;
        dataArray[ curPos++ ] = ( value >> 8 ) & 0xFF;
        dataArray[ curPos++ ] = value & 0xFF;
        if( curPos > dataSize )
            dataSize = curPos;
        return this;
    }

    Serializator& Set( const int16& value )
    {
        GrowBuffer( curPos + 2 );
        dataArray[ curPos++ ] = ( value >> 8 ) & 0xFF;
        dataArray[ curPos++ ] = value & 0xFF;
        if( curPos > dataSize )
            dataSize = curPos;
        return this;
    }

    Serializator& Set( const int8& value )
    {
        GrowBuffer( curPos + 1 );
        dataArray[ curPos++ ] = value;
        if( curPos > dataSize )
            dataSize = curPos;
        return this;
    }

    Serializator& Set( const uint64& value )
    {
        GrowBuffer( curPos + 8 );
        dataArray[ curPos++ ] = ( value >> 56 ) & 0xFF;
        dataArray[ curPos++ ] = ( value >> 48 ) & 0xFF;
        dataArray[ curPos++ ] = ( value >> 40 ) & 0xFF;
        dataArray[ curPos++ ] = ( value >> 32 ) & 0xFF;
        dataArray[ curPos++ ] = ( value >> 24 ) & 0xFF;
        dataArray[ curPos++ ] = ( value >> 16 ) & 0xFF;
        dataArray[ curPos++ ] = ( value >> 8 ) & 0xFF;
        dataArray[ curPos++ ] = value & 0xFF;
        if( curPos > dataSize )
            dataSize = curPos;
        return this;
    }

    Serializator& Set( const uint32& value )
    {
        GrowBuffer( curPos + 4 );
        dataArray[ curPos++ ] = ( value >> 24 ) & 0xFF;
        dataArray[ curPos++ ] = ( value >> 16 ) & 0xFF;
        dataArray[ curPos++ ] = ( value >> 8 ) & 0xFF;
        dataArray[ curPos++ ] = value & 0xFF;
        if( curPos > dataSize )
            dataSize = curPos;
        return this;
    }

    Serializator& Set( const uint16& value )
    {
        GrowBuffer( curPos + 2 );
        dataArray[ curPos++ ] = ( value >> 8 ) & 0xFF;
        dataArray[ curPos++ ] = value & 0xFF;
        if( curPos > dataSize )
            dataSize = curPos;
        return this;
    }

    Serializator& Set( const uint8& value )
    {
        GrowBuffer( curPos + 1 );
        dataArray[ curPos++ ] = value;
        if( curPos > dataSize )
            dataSize = curPos;
        return this;
    }

    Serializator& Set( const bool& value )
    {
        GrowBuffer( curPos + 1 );
        dataArray[ curPos++ ] = value ? 1 : 0;
        if( curPos > dataSize )
            dataSize = curPos;
        return this;
    }

    Serializator& Set( const string& value )
    {
        uint len = value.rawLength();
        GrowBuffer( curPos + len + 1 );
        for( uint i = 0; i < len; i++ )
            dataArray[ curPos++ ] = value.rawGet( i );
        dataArray[ curPos++ ] = 0;
        if( curPos > dataSize )
            dataSize = curPos;
        return this;
    }

    Serializator& Set( const int64[]& values )
    {
        uint valuesLen = values.length();
        uint len = 4 + valuesLen * 8;
        GrowBuffer( curPos + len );
        Set( valuesLen );
        for( uint i = 0, j = valuesLen; i < j; i++ )
            Set( values[ i ] );
        if( curPos > dataSize )
            dataSize = curPos;
        return this;
    }

    Serializator& Set( const int32[]& values )
    {
        uint valuesLen = values.length();
        uint len = 4 + valuesLen * 4;
        GrowBuffer( curPos + len );
        Set( valuesLen );
        for( uint i = 0, j = valuesLen; i < j; i++ )
            Set( values[ i ] );
        if( curPos > dataSize )
            dataSize = curPos;
        return this;
    }

    Serializator& Set( const int16[]& values )
    {
        uint valuesLen = values.length();
        uint len = 4 + valuesLen * 2;
        GrowBuffer( curPos + len );
        Set( valuesLen );
        for( uint i = 0, j = valuesLen; i < j; i++ )
            Set( values[ i ] );
        if( curPos > dataSize )
            dataSize = curPos;
        return this;
    }

    Serializator& Set( const int8[]& values )
    {
        uint valuesLen = values.length();
        uint len = 4 + valuesLen;
        GrowBuffer( curPos + len );
        Set( valuesLen );
        for( uint i = 0, j = valuesLen; i < j; i++ )
            Set( values[ i ] );
        if( curPos > dataSize )
            dataSize = curPos;
        return this;
    }

    Serializator& Set( const uint64[]& values )
    {
        uint valuesLen = values.length();
        uint len = 4 + valuesLen * 8;
        GrowBuffer( curPos + len );
        Set( valuesLen );
        for( uint i = 0, j = valuesLen; i < j; i++ )
            Set( values[ i ] );
        if( curPos > dataSize )
            dataSize = curPos;
        return this;
    }

    Serializator& Set( const uint32[]& values )
    {
        uint valuesLen = values.length();
        uint len = 4 + valuesLen * 4;
        GrowBuffer( curPos + len );
        Set( valuesLen );
        for( uint i = 0, j = valuesLen; i < j; i++ )
            Set( values[ i ] );
        if( curPos > dataSize )
            dataSize = curPos;
        return this;
    }

    Serializator& Set( const uint16[]& values )
    {
        uint valuesLen = values.length();
        uint len = 4 + valuesLen * 2;
        GrowBuffer( curPos + len );
        Set( valuesLen );
        for( uint i = 0, j = valuesLen; i < j; i++ )
            Set( values[ i ] );
        if( curPos > dataSize )
            dataSize = curPos;
        return this;
    }

    Serializator& Set( const uint8[]& values )
    {
        uint valuesLen = values.length();
        uint len = 4 + valuesLen;
        GrowBuffer( curPos + len );
        Set( valuesLen );
        for( uint i = 0, j = valuesLen; i < j; i++ )
            Set( values[ i ] );
        if( curPos > dataSize )
            dataSize = curPos;
        return this;
    }

    Serializator& Set( const bool[]& values )
    {
        uint valuesLen = values.length();
        uint len = 4 + valuesLen;
        GrowBuffer( curPos + len );
        Set( valuesLen );
        for( uint i = 0, j = valuesLen; i < j; i++ )
            Set( values[ i ] );
        if( curPos > dataSize )
            dataSize = curPos;
        return this;
    }

    Serializator& Set( const string[]& values )
    {
        uint valuesLen = values.length();
        uint len = 4 + valuesLen;     // Length and zeros
        for( uint i = 0, j = valuesLen; i < j; i++ )
            len += values[ i ].length();
        GrowBuffer( curPos + len );
        Set( valuesLen );
        for( uint i = 0, j = valuesLen; i < j; i++ )
            Set( values[ i ] );
        if( curPos > dataSize )
            dataSize = curPos;
        return this;
    }

    #ifdef __SERVER
    Serializator& Set( const Critter& cr )
    {
        GrowBuffer( curPos + 4 );
        uint value = cr.Id;
        dataArray[ curPos++ ] = ( value >> 24 ) & 0xFF;
        dataArray[ curPos++ ] = ( value >> 16 ) & 0xFF;
        dataArray[ curPos++ ] = ( value >> 8 ) & 0xFF;
        dataArray[ curPos++ ] = value & 0xFF;
        if( curPos > dataSize )
            dataSize = curPos;
        return this;
    }

    Serializator& Set( const Item& item )
    {
        GrowBuffer( curPos + 4 );
        uint value = item.Id;
        dataArray[ curPos++ ] = ( value >> 24 ) & 0xFF;
        dataArray[ curPos++ ] = ( value >> 16 ) & 0xFF;
        dataArray[ curPos++ ] = ( value >> 8 ) & 0xFF;
        dataArray[ curPos++ ] = value & 0xFF;
        if( curPos > dataSize )
            dataSize = curPos;
        return this;
    }
    #endif

    Serializator& Get( int64& value )
    {
        value = 0;
        if( curPos + 8 > dataSize )
            return this;
        value |= dataArray[ curPos++ ] << 56;
        value |= dataArray[ curPos++ ] << 48;
        value |= dataArray[ curPos++ ] << 40;
        value |= dataArray[ curPos++ ] << 32;
        value |= dataArray[ curPos++ ] << 24;
        value |= dataArray[ curPos++ ] << 16;
        value |= dataArray[ curPos++ ] << 8;
        value |= dataArray[ curPos++ ];
        return this;
    }

    Serializator& Get( int32& value )
    {
        value = 0;
        if( curPos + 4 > dataSize )
            return this;
        value |= dataArray[ curPos++ ] << 24;
        value |= dataArray[ curPos++ ] << 16;
        value |= dataArray[ curPos++ ] << 8;
        value |= dataArray[ curPos++ ];
        return this;
    }

    Serializator& Get( int16& value )
    {
        value = 0;
        if( curPos + 2 > dataSize )
            return this;
        value |= dataArray[ curPos++ ] << 8;
        value |= dataArray[ curPos++ ];
        return this;
    }

    Serializator& Get( int8& value )
    {
        value = 0;
        if( curPos + 1 > dataSize )
            return this;
        value = dataArray[ curPos++ ];
        return this;
    }

    Serializator& Get( uint64& value )
    {
        value = 0;
        if( curPos + 8 > dataSize )
            return this;
        value |= dataArray[ curPos++ ] << 56;
        value |= dataArray[ curPos++ ] << 48;
        value |= dataArray[ curPos++ ] << 40;
        value |= dataArray[ curPos++ ] << 32;
        value |= dataArray[ curPos++ ] << 24;
        value |= dataArray[ curPos++ ] << 16;
        value |= dataArray[ curPos++ ] << 8;
        value |= dataArray[ curPos++ ];
        return this;
    }

    Serializator& Get( uint32& value )
    {
        value = 0;
        if( curPos + 4 > dataSize )
            return this;
        value |= dataArray[ curPos++ ] << 24;
        value |= dataArray[ curPos++ ] << 16;
        value |= dataArray[ curPos++ ] << 8;
        value |= dataArray[ curPos++ ];
        return this;
    }

    Serializator& Get( uint16& value )
    {
        value = 0;
        if( curPos + 2 > dataSize )
            return this;
        value |= dataArray[ curPos++ ] << 8;
        value |= dataArray[ curPos++ ];
        return this;
    }

    Serializator& Get( uint8& value )
    {
        value = 0;
        if( curPos + 1 > dataSize )
            return this;
        value = dataArray[ curPos++ ];
        return this;
    }

    Serializator& Get( bool& value )
    {
        value = false;
        if( curPos + 1 > dataSize )
            return this;
        value = dataArray[ curPos++ ] == 1 ? true : false;
        return this;
    }

    Serializator& Get( string& str )
    {
        uint len = 0;
        for( uint i = curPos; ; i++ )
        {
            if( i == dataSize )
            {
                str = "";
                return this;
            }
            if( dataArray[ i ] == 0 )
            {
                len = i - curPos;
                break;
            }
        }
        str.rawResize( len );
        for( uint i = 0; i < len; i++ )
            str.rawSet( i, dataArray[ curPos++ ] );
        curPos++;         // Skip zero
        return this;
    }

    Serializator& Get( int64[]& values )
    {
        uint valuesLen = 0;
        Get( valuesLen );
        values.resize( valuesLen );
        for( uint i = 0; i < valuesLen; i++ )
            Get( values[ i ] );
        return this;
    }

    Serializator& Get( int32[]& values )
    {
        uint valuesLen = 0;
        Get( valuesLen );
        values.resize( valuesLen );
        for( uint i = 0; i < valuesLen; i++ )
            Get( values[ i ] );
        return this;
    }

    Serializator& Get( int16[]& values )
    {
        uint valuesLen = 0;
        Get( valuesLen );
        values.resize( valuesLen );
        for( uint i = 0; i < valuesLen; i++ )
            Get( values[ i ] );
        return this;
    }

    Serializator& Get( int8[]& values )
    {
        uint valuesLen = 0;
        Get( valuesLen );
        values.resize( valuesLen );
        for( uint i = 0; i < valuesLen; i++ )
            Get( values[ i ] );
        return this;
    }

    Serializator& Get( uint64[]& values )
    {
        uint valuesLen = 0;
        Get( valuesLen );
        values.resize( valuesLen );
        for( uint i = 0; i < valuesLen; i++ )
            Get( values[ i ] );
        return this;
    }

    Serializator& Get( uint32[]& values )
    {
        uint valuesLen = 0;
        Get( valuesLen );
        values.resize( valuesLen );
        for( uint i = 0; i < valuesLen; i++ )
            Get( values[ i ] );
        return this;
    }

    Serializator& Get( uint16[]& values )
    {
        uint valuesLen = 0;
        Get( valuesLen );
        values.resize( valuesLen );
        for( uint i = 0; i < valuesLen; i++ )
            Get( values[ i ] );
        return this;
    }

    Serializator& Get( uint8[]& values )
    {
        uint valuesLen = 0;
        Get( valuesLen );
        values.resize( valuesLen );
        for( uint i = 0; i < valuesLen; i++ )
            Get( values[ i ] );
        return this;
    }

    Serializator& Get( bool[]& values )
    {
        uint valuesLen = 0;
        Get( valuesLen );
        values.resize( valuesLen );
        for( uint i = 0; i < valuesLen; i++ )
            Get( values[ i ] );
        return this;
    }

    Serializator& Get( string[]& values )
    {
        uint valuesLen = 0;
        Get( valuesLen );
        values.resize( valuesLen );
        for( uint i = 0; i < valuesLen; i++ )
            Get( values[ i ] );
        return this;
    }

    #ifdef __SERVER
    Serializator& Get( Critter@& cr )
    {
        @cr = null;
        if( curPos + 4 > dataSize )
            return this;
        uint id = 0;
        id |= dataArray[ curPos++ ] << 24;
        id |= dataArray[ curPos++ ] << 16;
        id |= dataArray[ curPos++ ] << 8;
        id |= dataArray[ curPos++ ];
        @cr = ::GetCritter( id );
        return this;
    }

    Serializator& Get( Item@& item )
    {
        @item = null;
        if( curPos + 4 > dataSize )
            return this;
        uint id = 0;
        id |= dataArray[ curPos++ ] << 24;
        id |= dataArray[ curPos++ ] << 16;
        id |= dataArray[ curPos++ ] << 8;
        id |= dataArray[ curPos++ ];
        @item = ::GetItem( id );
        return this;
    }
    #endif
};

Commits for fonline_sdk/Modules/Core/Serializator.fosh

Diff revisions: vs.
Revision Author Commited Message
606 Diff Diff cvet picture cvet Mon 23 May, 2016 15:41:24 +0000

Реорганизация движка.

571 Diff Diff cvet picture cvet Sat 24 Oct, 2015 10:17:44 +0000

Реорганизация контента.
Настройка Core скриптов.

566 Diff Diff cvet picture cvet Sat 24 Oct, 2015 10:08:47 +0000

Реорганизация контента.
Перемещение Core скриптов.

565 Diff Diff cvet picture cvet Sat 24 Oct, 2015 09:57:00 +0000

Реорганизация контента.
Переименование скриптов.

537 Diff Diff cvet picture cvet Mon 21 Sep, 2015 15:06:06 +0000

Введено некое подобие модульной системы организации контента.
Теперь все будет лежать не по отдельным папакам. т.е. скрипты в scripts, диалоги в dialogs и т.п., а в общей папке Modules, в которой можно группировать файлы как удобно.
Предполагается, что папки верхнего уровня это наименование отдельного модуля.
Любые папки в Modules (включая подпапки) начинающиеся с подчеркивания ‘_’ не будут обрабатываться.
Папки с именем ‘Resources’ будут паковаться в ресурсы клиента.
А в папках ‘Texts’ сервер будет искать файлы локализации текстов.
Пока есть только один модуль ‘TLA’, но в будущем он будет разделен на отдельные, например: Core, Traders, Combat и т.п.
Но нужно помнить, что пространство имен у всех контентных файлов (диалоги, прототипы и т.п.) одно и наличие двух одинаковых в разных папках не допускается.

506 Diff Diff cvet picture cvet Thu 28 May, 2015 21:28:37 +0000

Удалена система игровых переменных GameVar (Global/Local/Unicum).
Удалена система хранения данных AnyData.
Вместо них теперь используется новая система свойств.

Свойства типа dict теперь в значении могут иметь не только простой тип данных, но и массив простого типа данных.
Например dict< uint, uint8[] >.

Кэш сервера перенесен в отдельную папку cache.
Теперь для очистки кэша достаточно удалить эту папку, или воспользоваться батником CleanCache.bat/sh.

CreateTimeEvent теперь никогда не возвращает 0, а при ошибке вызывает исключение.

Изменены расширения сохранений клиентов на .foclient, и сохранений мира на .foworld.

Произведены различные фиксы стабильности связанные с нововведениями.

Пользователем Felinssa произведен рефакторинг кода по переносу всех оставшихся переменных на новую систему свойств.

503 Diff Diff cvet picture cvet Sat 16 May, 2015 07:33:53 +0000

Сигнатура скриптов изменена с первых трех символов ‘//$’ на наличие в первой строке символов ‘FOS’.

500 Diff Diff cvet picture cvet Mon 11 May, 2015 14:15:04 +0000

Изменен принцип загрузки скриптов.
Теперь в каждом файле скрипта, первой строкой, должна присутствовать сигнатура ‘//$’ после которой перечисляются следующие идентификаторы:
Server - серверный скрипт;
Client - клиентский скрипт;
Mapper - скрипт маппера;
Common - серверный, клиентский и скрипт маппера;
Header - заголовочный файл, не загружается как модуль, без этого скрипт будет загружен как модуль.
Идентификаторов можут быть несколько и перечисляться через пробел.
Пример:
//$ Server Client Header
означает, что это заголовочный файл для сервера и клиента.
Все скрипты загружаются автоматически из папки Server/scripts, необходимости в scripts.cfg больше нет.

429 Diff Diff cvet picture cvet Sat 21 Jun, 2014 20:34:17 +0000

С данной ревизии сдк начинается перевод хардкод гуи в скрипты.
На данный момент создана базовая архитектура новой системы, которая состоит из
- редактора интерфейса Tools/InterfaceEditor;
- gui.fos - ядро системы, которое осуществляет работу интерфейса;
- gui_h.fos - базовые классы и пользовательский функционал для работы с интерфейсом;
- gui_screens.fos - автоматически сгенерированный скрипт в InterfaceEditor, где находится логика работы окон.
- gui_screens_stuff.fos - скрипт, который включается в gui_screens.fos, для внесения функционала вручную, который будет там использоваться.
Постепенно интерфейс будет замещаться, а по окончании хардкод будет исключен из клиента.
Соответственно произошли правки в скриптах, связанные с удалением старой системы и вводом новой.
Еще раз подчеркну, что текущая версия только начало работы над новым гуи, и в течении нескольких месяцев система и редактор будут дорабатываться.

API нового гуи находится в начале скрипта gui_h.fos.
Примеры использования новой системы находятся в обновленных скриптах client_screen_test.fos и radio.fos. А так же в автоматически сгенерированном скрипте gui_screens.fos.
Несколько советов:
- помечайте колбеки событий объектов гуи (начинаются с ‘On’) как override, на случай, если допустите ошибку в имени или параметрах, что бы компилятор вас предупредил об этом;
- не используйте методы и параметры начинающиеся с подчеркивания в базовых классах gui, они для внутренней работы системы и их поведение может меняться со временем.

Редактор интерфейса состоит из программы InterfaceEditor.exe и файлов для хранения информации о интерфейсе.
Расширение .fogui - отдельное окно;
Расширение .foguischeme - схема набора окон, нужно будет для моддинга стандартного интерфейса.
На данный момент взаимодействие с гуи осуществляется посредством контекстного меню вызываемого правой кнопкой мыши на панели GUI.

В этой ревизии уже замещен экран логина в игру.
Перемещено рисование информации по F1 в скрипты.

AngelScript обновлен до ревизии 1959, версия 2.29.0.
По скриптам произошло много правок, в связи с новыми ворнингами при компиляции.
В скрипты включен аддон AngelScript weakref.

Для обработки хардкод ввода добавлены функции
void HandleHardcodedScreenMouse(int screen, int button, bool down, bool move)
void HandleHardcodedScreenKey(int screen, uint8 key, string@ text, bool down)
они будут использоваться для работы с хардкод гуи на время его переноса.

На время миграции интерфейса в скрипты добавлена функция
string@ CustomCall(string& command, string& separator = “ ”)
нужна для работы с движком, вызова некоторых его функций, которые не нужно выносить в скрипты, но необходимость в вызове существует.

Добавлена глобальная функция
void CloneObject(?&in, ?&out, bool copy)
с помощью которой можно создавать копии объектов не

Переработаны функции DrawSprite, теперь они имеют следующие сигнатуры
void DrawSprite(uint sprId, int frameIndex, int x, int y, uint color = 0, bool applyOffsets = false)
void DrawSprite(uint sprId, int frameIndex, int x, int y, int w, int h, bool zoom = false, uint color = 0, bool applyOffsets = false)
void DrawSpritePattern(uint sprId, int frameIndex, int x, int y, int w, int h, int sprWidth, int sprHeight, uint color = 0)
bool zoom - если true, то изображение сохраняет пропорции, если false, то растягивается.

В функции GetTextInfo теперь вместо ссылки для текста используется указатель
void GetTextInfo(string& text...
void GetTextInfo(string@ text...
теперь при передаче null будет рассчитываться максимальное количество строк, которое может вместиться в заданную область.

В функцию HideScreen теперь не передаются какие-либо параметры, а в функцию ShowScreen теперь вместо int p0, p1, p2 можно опционально передать dictionary, который потом уже можно будет использовать в GUIObject::OnInit
void ShowScreen(int screen, dictionary@ params = null)

При передаче в функцию MouseClick значения -1 в параметр cursor, то смены курсора не будет.

Исправлена работа функции GetMonitorHex, когда не учитывались параметры x и y.

Для обработки пользовательского ввода создан скрипт input.fos.
Туда перемещена из движка обработка всех горячих клавиш.

Добавлены глобальные переменные
int __SoundVolume - регулировка громкости звуков (0..100);
int __MusicVolume - регулировка громкости музыки (0..100);
bool __DebugInfo - отладочная информация по F1.

Переделано обозначение версий сервера, клиента и маппера, теперь оно будет обозначать номер ревизии сдк.

Добавлена зарезервированная функция для скриптов клиента и маппера
void finish()
которая вызывается в момент выхода из программы.
Нужно учитывать, что функция может не вызваться, если произошло падение клиента или он был закрыт по Alt+F4. ????

Добавлена зарезервированная функция для скриптов клиента, которая вызывается при добавлении игрового сообщения
void message_box( string& messageText, int messageType, bool scriptCall )
string& messageText - текст сообщения, можно модифицировать для движка;
int messageType - тип сообщения;
bool scriptCall - был ли вызов инициирован со скриптов функцией Message или движком.

Изменены сигнатуры функций mouse_down, mouse_up, mouse_move, key_down, key_up.

Для работы с кешем на строне клиента добавлены функции
void SetCacheData(const string& name, const uint8[]& data)
void SetCacheData(const string& name, const uint8[]& data, uint dataSize)
bool GetCacheData(const string& name, uint8[]& data)
void SetCacheDataStr(const string& name, const string& data)
string@ GetCacheDataStr(const string& name)
bool IsCacheData(const string& name)
void EraseCacheData(const string& name)
const string& name - имя данных;
const uint8[]& data - данные;
uint dataSize - длинна данных;
const string& data - данные.
Теперь класс serializator.fos может работать и в клиенте.

Исправлен баг с перегенерацией клиентских скриптов, баг с 428 ревизии.

Вычисление смещение текстуры в аталсе теперь происходит в шейдере
TexCoord.x = ( InTexCoord.x * ColorMapAtlasOffset.z ) + ColorMapAtlasOffset.x;
TexCoord.y = ( InTexCoord.y * ColorMapAtlasOffset.w ) + ColorMapAtlasOffset.y;
соответсвенно добавлена переменная ColorMapAtlasOffset.
Вместо атрибута InTexCoordBase теперь передается вторая текстурная координата TexCoord2.
См. файл Client/data/effects/ReadMe.txt

В статистике памяти сервера добавлен учет памяти массивов.

Для строк добавлены методы
bool startsWith(const string &in) const - начинается ли строка с переданной;
bool endsWith(const string &in) const - кончается ли строка переданной.
Так же все глоабльные функции для работы со строками получили соответствующие методы в самом классе
string@ substring(int start, int count = -1)
int findFirst(const string &in, int start = 0)
int findLast(const string &in, int start = 0)
int findFirstOf(const string &in, int start = 0)
int findFirstNotOf(const string &in, int start = 0)
int findLastOf(const string &in, int start = 0)
int findLastNotOf(const string &in, int start = 0)
array<string@>@ split(const string &in)
string@ toLower()
string@ toUpper()

400 cvet picture cvet Sat 27 Apr, 2013 19:27:18 +0000

Добавлена поддержка Unicode, кодировка UTF-8.
Все текстовые файлы переведены в кодировку UTF-8 (без BOM).

Обновлен весь инструментарий на предмет совместимости с юникодом.
В том числе редактор прототипов (ObjectEditor). (by Ghosthack)

Была исправлена работоспособность и модифицирована глобальная функция клиента/маппера
void KeyboardPress(uint8 key1, uint8 key2, string@+ key1Text = null, string@+ key2Text = null)
добавлены опциональные параметры key1Text/key2Text, которые будут переданы в обработчики key_up/key_down вместе с переменными key1/key2.

Для обработки ввода была добавлена константа DIK_CLIPBOARD_PASTE, событие которой означает вставку текста с буфера обмена.

Изменен принцип ввода с клавиатуры и работы с языком ввода.
В зарезервированные функции клиента/маппера key_down/key_up теперь передается параметр string& keyText, в котором будет записан текст на нужном языке, базирующийся на текущем языке ввода ОС.
Переключение раскладки клавиатуры теперь контролируется ОС, а не программой, ввиду чего была убрана глобальная переменная ChangeLang и соответствующие ей константы. Так же удалена глобальная функция int GetKeybLang().
Удалена функция перевода текста из одного языка в другой по кнопке Pause (пользуйтесь сторонними программами, например, PuntoSwicher).

Проверки корректности имени перенесена в скрипты, клиент/сервер проверяют только длину, корректность UTF-8 символов и отсутствие знака ‘*’ (которым в некоторых местах потом заменяется пробел).
В зарезервированную клиентскую функцию 'bool player_data_check( string& name, int[]& data ) добавлен параметр ‘string name’ для проверки его корректности перед регистрацией.

В скрипты сервера/клиента/маппера добавлены глобальные функции:
uint DecodeUTF8(const string& text, uint& length) - декодирование символа из текста (const string& text) с возвращением его UCS кода и длинны кода в строке (uint& length). Если символ не распознан, то будет возвращен код 0xFFFD.
string@ EncodeUTF8(uint ucs) - кодирование UCS кода в строку.

Изменился формат файлов шрифта fofnt, теперь в первую очередь должен присутствовать тег с версией формата (Version).
- изменился формат тега Letter, c “Letter 65 # 'A'” на “Letter 'A'”;
- добавлен тег LineHeight, который указывает на высоту строки шрифта (если не указан, то высота берется по самому большому символу из всего списка);
- в имя атласа для шрифта Image можно добавить символ ‘*’, тогда цвет текстуры нормализуется с любого на RGB [128, 128, 128] (только для OpenGL рендера);
- метка ‘End’ прекратит парсинг файла (для отладки).
Эти шрифты теперь кешируются в бинарном виде, их загрузка теперь будет очень быстрой, после первого запуска. Рекеширование идет, если изменилось время записи файла.
В основной шрифт Default.fofnt добавлены дополнительные символы юникода из шрифта DefaultExt.fnt (хотя сам шрифт нигде не используется), в связи с чем клиент теперь поддерживает не только английский и русский язык, как минимум для шрифта по умолчанию.

Обновлена работа со строками.

Индексный оператор теперь возвращает строку содержащую нужный символ, соответственно сравнивать теперь необходимо не с символьными константами (‘X’), а со строками (“X”). Пример:
string s = “abcd”; // s[ 1 ] вернет "b"
string s = “abcd”; // s[ 4 ] исключение - выход за пределы массива
При присвоении с индексным оператором идет удаление символа и вставка присваиваемой строки, примеры:
string s = “abcd”; s[ 1 ] = “g”; // s == "agcd"
string s = “abcd”; s[ 2 ] = “xyz”; // s == "abxyzd"
string s = “abcd”; s[ 1 ] = ""; // s == "acd"
Появилась возможность индексировать строки с помощью отрицательных значений. Это применимо так же к глобальным функциям для работы со строками (substr, findFirst, findLast и т.п.) для параметра ‘int start’. Примеры:
string s = “abcd”; // s[ -1 ] вернет "d"
string s = “abcs”; // s[ -100 ] исключение - выход за пределы массива
string s = “abcd”; s[ -3 ] = “X”; // s == "aXcd"
string s = “abcd”; s[ -1 ] = ""; // s == "abc"

Метод length() теперь возвращает количество символов юникода в строке, а не количество байт, т.е. как метод lengthUTF8(), который сейчас удален (замену старому length() см. ниже).

Обновлены все функции для работы со строками (substr, findFirst, findLast и т.п.), теперь они так же работают с символами юникода, а не байтами.

Переименован метод resize(uint), см. ниже.

Для работы с байтами в строке добавлены следующие методы:
uint rawLength() const - вместо предыдущего length();
void rawResize(uint size) - вместо resize(uint);
uint8 rawGet(uint index) const - вместо старого индексного оператора;
void rawSet(uint index, uint8 value) - вместо старого индексного оператора.

Исправления по трехмерной графике.

Исправлена утечка памяти при работе с эффектами.

В формате fo3d тег Mesh теперь может принимать значение -1, это означает, что установка текстур, эффектов и отключения материалов (теги Texture, Effect, DesableSubset) будут касаться всех мешей в текущей модели. Так же теперь этот тег по умолчанию равен -1, а не 0 (т.е. установка для всех моделей, а не только для первой).

Исправлено использование эффектов в 3д моделях OpenGL ренеринга (до этого они не устанавливались и всегда использовались эффекты по умолчанию).

Другое.

Оптимизирована скорость загрузки карт (fomap) и прототипов (fopro) файлов.