Форум программистов, компьютерный форум, киберфорум
C++: Сети
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.56/18: Рейтинг темы: голосов - 18, средняя оценка - 4.56
0 / 0 / 0
Регистрация: 07.11.2010
Сообщений: 7

C++ includes или как исправить ошибки

07.11.2010, 15:57. Показов 3300. Ответов 4
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
1>------ Построение начато: проект: mineserver, Конфигурация: Release Win32 ------
1>  chat.cpp
1>..\src\chat.cpp(326): warning C4244: =: преобразование "double" в "int", возможна потеря данных
1>..\src\chat.cpp(327): warning C4244: =: преобразование "double" в "int", возможна потеря данных
1>..\src\chat.cpp(328): warning C4244: =: преобразование "double" в "int", возможна потеря данных
1>..\src\chat.cpp(376): error C3861: bufferevent_write: идентификатор не найден
1>  map.cpp
1>..\src\map.cpp(24): fatal error C1083: Не удается открыть файл включение: zlib.h: No such file or directory
1>  mineserver.cpp
1>..\src\mineserver.cpp(34): fatal error C1083: Не удается открыть файл включение: zlib.h: No such file or directory
1>  sockets.cpp
1>..\src\sockets.cpp(33): fatal error C1083: Не удается открыть файл включение: zlib.h: No such file or directory
1>  user.cpp
1>..\src\user.cpp(19): fatal error C1083: Не удается открыть файл включение: zlib.h: No such file or directory
========== Построение: успешно: 0, с ошибками: 1, без изменений: 0, пропущено: 0 ==========
Как устранить данные ошибки? Использую VS C++ 2010.

Прошу не сильно ругать, только начинаю...
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
07.11.2010, 15:57
Ответы с готовыми решениями:

Kohana 3 или как исправить ошибки
Всем привет! Имеется локальный сервер МАМР с установленной Kohana 3, для учебы. Фреймворк доступен по адресу localhost:8888/kohana/ На...

Исправить ошибки в коде или пояснить как правильно запустить
Добрый вечер,нужна помощь есть текст программы написанный в 2010 с++ ,немогу запустить в 2013,выдает ошибку что неправильная...

Пожалуйста нужно исправить ошибки в коде или написать его заного
Тема курсовой роботы: Разработка программы для численного решения уравлений методом половинного деления Помогите пожалуйста написать...

4
Бродяга
 Аватар для dihlofos
315 / 269 / 56
Регистрация: 27.08.2010
Сообщений: 553
07.11.2010, 15:59
Tocher,где код?
0
0 / 0 / 0
Регистрация: 07.11.2010
Сообщений: 7
07.11.2010, 16:29  [ТС]
chat.cpp
C++
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
#include <cstdlib>
#include <cstdio>
#include <iostream>
#include <deque>
#include <fstream>
#include <vector>
#include <ctime>
#ifdef WIN32
  #include <winsock2.h>
#endif
 
#include "logger.h"
#include "constants.h"
 
#include "tools.h"
#include "map.h"
#include "user.h"
#include "chat.h"
#include "config.h"
 
 
Chat &Chat::get()
{
  static Chat instance;
  return instance;
}
 
 
bool Chat::checkMotd(std::string motdFile)
{
  //
  // Create motdfile is it doesn't exist
  //
  std::ifstream ifs(motdFile.c_str());
 
  // If file does not exist
  if(ifs.fail())
  {
    std::cout << "> Warning: " << motdFile << " not found. Creating..." << std::endl;
 
    std::ofstream motdofs(motdFile.c_str());
    motdofs << DEFAULTMOTDFILE << std::endl;
    motdofs.close();
  }
 
  ifs.close();
 
  return true;
}
 
bool Chat::loadAdmins(std::string adminFile)
{
  // Read admins to deque
  std::ifstream ifs(adminFile.c_str());
 
  // If file does not exist
  if(ifs.fail())
  {
    std::cout << "> Warning: " << adminFile << " not found. Creating..." << std::endl;
 
    std::ofstream adminofs(adminFile.c_str());
    adminofs << DEFAULTADMINFILE << std::endl;
    adminofs.close();
 
    return true;
  }
 
  std::string temp;
 
  admins.clear();
 
  while(getline(ifs, temp))
  {
    // If not commentline
    if(temp[0] != COMMENTPREFIX)
    {
        admins.push_back(temp);
    }
  }
  ifs.close();
 
  std::cout << "Loaded admins from " << adminFile << std::endl;
 
  return true;
}
 
bool Chat::sendUserlist(User *user) {
  this->sendMsg(user, COLOR_BLUE + "[ Players online ]", USER);
 
  for(unsigned int i=0;i<Users.size();i++)
  {
    this->sendMsg(user, "> " + Users[i]->nick, USER);
  }
 
  return true;
}
 
std::deque<std::string> Chat::parseCmd(std::string cmd)
{
  int del;
  std::deque<std::string> temp;
 
  while(cmd.length() > 0)
  {
    while(cmd[0] == ' ')
      cmd = cmd.substr(1);
 
    del = cmd.find(' ');
 
    if(del > -1)
    {
      temp.push_back(cmd.substr(0, del));
      cmd = cmd.substr(del+1);
    }
    else
    {
      temp.push_back(cmd);
      break;
    }
  }
 
  if(temp.empty())
    temp.push_back("empty");
 
  return temp;
}
 
bool Chat::handleMsg(User *user, std::string msg)
{
  // Timestamp
  time_t rawTime = time(NULL);
  struct tm* Tm = localtime(&rawTime);
 
  std::string timeStamp (asctime(Tm));
 
  timeStamp = timeStamp.substr(11, 5);
 
  //
  // Chat commands
  //
 
  // Servermsg (Admin-only)
  if(msg[0] == SERVERMSGPREFIX && user->admin)
  {
    // Decorate server message
    msg = COLOR_RED + "[!] " + COLOR_GREEN + msg.substr(1);
    this->sendMsg(user, msg, ALL);
  }
 
  // Command
  else if(msg[0] == CHATCMDPREFIX)
  {
    std::deque<std::string> cmd = this->parseCmd(msg.substr(1));
 
    // Playerlist
    if(cmd[0] == "players")
    {
      this->sendUserlist(user);
    }
 
    // About server
    else if(cmd[0] == "about")
    {
      this->sendMsg(user, COLOR_DARK_MAGENTA + "SERVER:" + COLOR_RED + " Mineserver v." + VERSION, USER);
    }
 
    //
    // Admin commands
    //
 
    // Save map
    else if((cmd[0] == "save") && user->admin)
    {
      Map::get().saveWholeMap();
      this->sendMsg(user, COLOR_DARK_MAGENTA + "SERVER:" + COLOR_RED + " Saved map to disc", USER);
    }
 
    // Kick user
    else if((cmd[0] == "kick") && user->admin)
    {
      cmd.pop_front();
 
      if(!cmd.empty())
      {
        LOG("Kicking: " + cmd[0]);
 
        // Get coordinates
        User* tUser = getUserByNick(cmd[0]);
 
        if(tUser != false)
        {
          cmd.pop_front();
          std::string kickMsg = DEFAULTKICKMSG;
 
          if(!cmd.empty())
          {
            kickMsg = "";
 
            while(!cmd.empty())
            {
              kickMsg += cmd[0] + " ";
              cmd.pop_front();
            }
          }
 
          tUser->kick(kickMsg);
 
          LOG("Kicked!");
        }
        else
        {
          this->sendMsg(user, COLOR_DARK_MAGENTA + "Error!" + COLOR_RED + " User " + cmd[0] + " not found (See /players)", USER);
        }
      }
      else
      {
        this->sendMsg(user, COLOR_DARK_MAGENTA + "Error!" + COLOR_RED + " Usage: /kick user [reason]", USER);
      }
    }
 
    // Teleport to coordinates
    else if((cmd[0] == "ctp") && user->admin)
    {
      cmd.pop_front();
 
      if(cmd.size() > 2)
      {
        LOG(user->nick + " teleport to: " + cmd[0] + " " + cmd[1] + " " + cmd[2]);
 
        double x = atof(cmd[0].c_str());
        double y = atof(cmd[1].c_str());
        double z = atof(cmd[2].c_str());
 
        user->teleport(x, y, z);
      }
    }
 
    // Teleport to user
    else if((cmd[0] == "tp") && user->admin && (cmd.size() == 2))
    {
      cmd.pop_front();
 
      LOG(user->nick + " teleport to: " + cmd[0]);
 
      // Get coordinates
      User* tUser = getUserByNick(cmd[0]);
 
      if(tUser != false)
      {
        user->teleport(tUser->pos.x, tUser->pos.y+2, tUser->pos.z);
      }
      else
      {
        this->sendMsg(user, COLOR_DARK_MAGENTA + "Error!" + COLOR_RED + " User " + cmd[0] + " not found (See /players)", USER);
      }
    }
 
    // Teleport param1 to param2
    else if((cmd[0] == "tp") && user->admin && (cmd.size() == 3))
    {
      cmd.pop_front();
 
      LOG(user->nick + ": teleport " + cmd[0] + " to " + cmd[1]);
 
      // Get coordinates
      User* whatUser = getUserByNick(cmd[0]);
      User* toUser = getUserByNick(cmd[1]);
 
      if(whatUser != false && toUser != false)
      {
        whatUser->teleport(toUser->pos.x, toUser->pos.y+2, toUser->pos.z);
        this->sendMsg(user, COLOR_MAGENTA + "Teleported!", USER);
      }
      else
      {
        this->sendMsg(user, COLOR_DARK_MAGENTA + "Error!" + COLOR_RED + " User " + cmd[0] + " or " + cmd[1] + " not found (See /players)", USER);
      }
    }
 
    // Reload admins and configuration
    else if((cmd[0] == "reload") && user->admin)
    {
      cmd.pop_front();
 
      // Load admins
      this->loadAdmins(ADMINFILE);
 
      // Load config
      Conf::get().load(CONFIGFILE);
 
      this->sendMsg(user, COLOR_DARK_MAGENTA + "SERVER:" + COLOR_RED + " Reloaded admins and config", USER);
 
      // Note: Motd is loaded whenever new user joins
    }
 
    // Spawn items
    else if((cmd[0] == "give") && user->admin)
    {
      cmd.pop_front();
 
      User* tUser;
      int itemId;
      char itemCount = 1;
 
      if(cmd.size() > 1)
      {
        tUser = getUserByNick(cmd[0]);
        itemId = atoi(cmd[1].c_str());
 
        if(cmd.size() > 2)
          itemCount = atoi(cmd[2].c_str());
      }
      // Invalid parameters
      else
      {
        this->sendMsg(user, COLOR_DARK_MAGENTA + "Error!" + COLOR_RED + " Too few parameters", USER);
        return true;
      }
 
      if(tUser){
        spawnedItem item;
 
        item.EID = generateEID();
        item.item = itemId;
        item.count = itemCount;
        item.x = tUser->pos.x*32;
        item.y = tUser->pos.y*32;
        item.z = tUser->pos.z*32;
 
        Map::get().sendPickupSpawn(item);
 
        this->sendMsg(user, COLOR_RED + "Spawned some items!", USER);
      }
      else
      {
        this->sendMsg(user, COLOR_DARK_MAGENTA + "Error!" + COLOR_RED + " User " + cmd[0] + " not found (See /players)", USER);
      }
    }
  }
 
  // Normal message
  else
  {
    if(user->admin)
    {
      msg = timeStamp + " <"+ COLOR_DARK_MAGENTA + user->nick + COLOR_WHITE + "> " + msg;
    }
    else
    {
      msg = timeStamp + " <"+ user->nick + "> " + msg;
    }
 
    LOG(msg);
 
    this->sendMsg(user, msg, ALL);
  }
 
  return true;
}
 
bool Chat::sendMsg(User *user, std::string msg, int action = ALL)
{
  uint8 *tmpArray = new uint8 [msg.size()+3];
 
  tmpArray[0] = 0x03;
  tmpArray[1] = 0;
  tmpArray[2] = msg.size()&0xff;
 
  for(unsigned int i=0;i<msg.size();i++)
    tmpArray[i+3] = msg[i];
 
  if(action == ALL)
    user->sendAll(&tmpArray[0], msg.size()+3);
 
  if(action == USER)
    bufferevent_write(user->buf_ev, &tmpArray[0], msg.size()+3);
 
  if(action == OTHERS)
    user->sendOthers(&tmpArray[0], msg.size()+3);
 
  delete [] tmpArray;
 
  return true;
}
map.cpp
C++
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
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
#ifdef WIN32
  #define _CRTDBG_MAP_ALLOC
 
  #include <crtdbg.h>
  #include <conio.h>
  #include <direct.h>
  #include <winsock2.h>
#endif
#include <string.h>
#include <cstdlib>
#include <iostream>
#include <vector>
#include <cstdio>
#include <ctime>
#include <cmath>
#include <algorithm>
 
#include "logger.h"
 
#include <sys/stat.h>
 
#include "tools.h"
#include "map.h"
#include <zlib.h>
#include "user.h"
#include "nbt.h"
#include "config.h"
 
Map &Map::get()
{
  static Map instance;
  return instance;
}
 
void Map::posToId(int x, int z, uint32 *id)
{
  uint8 *id_pointer=reinterpret_cast<uint8 *>(id);
  putSint16(&id_pointer[0],x);
  putSint16(&id_pointer[2],z);  
}
 
void Map::idToPos(uint32 id, int *x, int *z)
{
  uint8 *id_pointer=reinterpret_cast<uint8 *>(&id);
  *x=getSint16(&id_pointer[0]);
  *z=getSint16(&id_pointer[2]);
}
 
void Map::initMap()
{
#ifdef MSDBG
  printf("initMap()\n");
#endif
 
  this->mapDirectory = Conf::get().value("mapdir");
  if(this->mapDirectory == "Not found!")
  {
    std::cout << "Error, mapdir not defined!" << std::endl;
    exit(EXIT_FAILURE);
  }
 
  std::string infile=mapDirectory+"/level.dat";
 
  struct stat stFileInfo;
  if(stat(infile.c_str(), &stFileInfo) != 0)
  {
    std::cout << "Error, map not found!" << std::endl;
    exit(EXIT_FAILURE);
  }
 
  // Read gzipped map file
  gzFile mapfile=gzopen(infile.c_str(), "rb");
  uint8 uncompressedData[200000];
  gzread(mapfile, &uncompressedData[0], 200000);
  gzclose(mapfile);
 
  // Save level data
  TAG_Compound(&uncompressedData[0], &levelInfo, true);
 
  if(!get_NBT_value(&levelInfo, "SpawnX", &spawnPos.x) ||
     !get_NBT_value(&levelInfo, "SpawnY", &spawnPos.y) ||
     !get_NBT_value(&levelInfo, "SpawnZ", &spawnPos.z))
  {
    std::cout << "Error, spawn pos not found from " << infile << "!" << std::endl;
    exit(EXIT_FAILURE);
  }
 
  std::cout << "Spawn: (" << spawnPos.x << "," << spawnPos.y << "," << spawnPos.z << ")" << std::endl;
}
 
void Map::freeMap() {}
 
NBT_struct *Map::getMapData(int x, int z)
{
#ifdef MSDBG
  printf("getMapData(x=%d, z=%d)\n", x, z);
#endif
 
  uint32 mapId;
  Map::posToId(x, z, &mapId);
 
  printf("Getting data for chunk %u\n", mapId);
 
  if (!maps.count(mapId) && !loadMap(x, z))
    return 0;
 
  // Update last used time
  mapLastused[mapId] = (int)time(0);
 
  // Data in memory
  return &maps[mapId];
}
 
bool Map::saveWholeMap()
{
#ifdef MSDBG
  printf("saveWholeMap()\n");
#endif
 
  for (std::map<uint32, NBT_struct>::const_iterator it = maps.begin(); it != maps.end(); ++it)
    saveMap(maps[it->first].x, maps[it->first].z);
  return true;
}
 
bool Map::generateLightMaps(int x, int z)
{
#ifdef MSDBG
  printf("generateLightMaps(x=%d, z=%d)\n", x, z);
#endif
 
  uint32 mapId;
  Map::posToId(x, z, &mapId);
 
  uint8 *skylight = maps[mapId].skylight;
  uint8 *blocklight = maps[mapId].blocklight;
  uint8 *blocks = maps[mapId].blocks;
 
  // Clear lightmaps
  memset(blocklight, 0, 16*16*128/2);
  memset(skylight, 0, 16*16*128/2);
 
  // Skylight
 
  // First set sunlight for all blocks until hit ground
  for(int block_x=0;block_x<16;block_x++)
  {
    for(int block_z=0;block_z<16;block_z++)
    {
      for(int block_y=127;block_y>0;block_y--)
      {
        int index = block_y + (block_z * 128) + (block_x * 128 * 16);
        int absolute_x = x*16+block_x;
        int absolute_z = z*16+block_z;
        uint8 block = blocks[index];
 
        setBlockLight(absolute_x, block_y, absolute_z, 0, 15, 2);
 
        if(stopLight[block] == -16)
        {
          break;
        }
      }
    }
  }
 
  // Loop again and now spread the light
  for(int block_x=0;block_x<16;block_x++)
  {
    for(int block_z=0;block_z<16;block_z++)
    {
      for(int block_y=127;block_y>=0;block_y--)
      {
        int index = block_y + (block_z * 128) + (block_x * 128 * 16);
        int absolute_x = x*16+block_x;
        int absolute_z = z*16+block_z;
        uint8 block = blocks[index];
 
        if(stopLight[block] == -16)
        {
          setBlockLight(absolute_x, block_y, absolute_z, 15+stopLight[block], 0, 1);
          break;
        }
        else
        {
          setBlockLight(absolute_x, block_y, absolute_z, 15, 0, 1);
          lightmapStep(absolute_x, block_y, absolute_z, 15+stopLight[block]);
        }
      }
    }
  }
 
  // Blocklight
  for(uint8 block_x=0;block_x<16;block_x++)
  {
    for(uint8 block_z=0;block_z<16;block_z++)
    {
      for(int block_y=127;block_y>=0;block_y--)
      {
        int index=block_y + (block_z * 128) + (block_x * 128 * 16);
 
        // If light emitting block
        if(emitLight[blocks[index]])
        {
          int absolute_x = x*16+block_x;
          int absolute_z = z*16+block_z;
          blocklightmapStep(absolute_x, block_y, absolute_z, emitLight[blocks[index]]);
        }
      }
    }
  }
 
  return true;
}
 
bool Map::blocklightmapStep(int x, int y, int z, int light)
{
#ifdef MSDBG
  printf("blocklightmapStep(x=%d, y=%d, z=%d, light=%d)\n", x, y, z, light);
#endif
 
  uint8 block, meta;
 
  // If no light, stop!
  if(light < 1) return false;
 
  for(uint8 i=0;i<6;i++)
  {
    // Going too high
    if((y == 127) && (i == 2))
    {
      i++;
    }
    // going negative
    else if((y == 0) && (i == 3))
    {
      i++;
    }
 
    int x_local = x;
    int y_local = y;
    int z_local = z;
 
    switch(i)
    {
      case 0: x_local++; break;
      case 1: x_local--; break;
      case 2: y_local++; break;
      case 3: y_local--; break;
      case 4: z_local++; break;
      case 5: z_local--; break;
    }
 
    if(getBlock(x_local, y_local, z_local, &block, &meta))
    {
      uint8 blocklight, skylight;
 
      getBlockLight(x_local, y_local, z_local, &blocklight, &skylight);
 
      if(blocklight<light+stopLight[block]-1)
      {
        setBlockLight(x_local, y_local, z_local, light+stopLight[block]-1, 15, 1);
 
        if(stopLight[block]!=-16)
          blocklightmapStep(x_local, y_local, z_local, light+stopLight[block]-1);
      }
    }
  }
 
  return true;
}
 
bool Map::lightmapStep(int x, int y, int z, int light)
{
#ifdef MSDBG
  printf("lightmapStep(x=%d, y=%d, z=%d, light=%d)\n", x, y, z, light);
#endif
 
  uint8 block, meta;
 
  // If no light, stop!
  if(light < 1)
    return false;
 
  for(uint8 i=0;i<6;i++)
  {
    // Going too high
    if(y==127 && i==2)
    {
      i++;
    }
    // going negative
    else if(y==0 && i==3)
    {
      i++;
    }
 
    int x_local = x;
    int y_local = y;
    int z_local = z;
 
    switch(i)
    {
      case 0: x_local++; break;
      case 1: x_local--; break;
      case 2: y_local++; break;
      case 3: y_local--; break;
      case 4: z_local++; break;
      case 5: z_local--; break;
    }
 
    //printf("getBlock(%d, %d, %d) (lightmapStep)\n", x_local, y_local, z_local);
    if(getBlock(x_local, y_local, z_local, &block, &meta))
    {
      uint8 blocklight, skylight;
 
      getBlockLight(x_local, y_local, z_local, &blocklight, &skylight);
 
      if(skylight<light+stopLight[block]-1)
      {
        setBlockLight(x_local, y_local, z_local, 0, light+stopLight[block]-1, 2);
 
        if(stopLight[block]!=-16)
          lightmapStep(x_local, y_local, z_local, light+stopLight[block]-1);
      }
    }
  }
 
  return true;
}
 
bool Map::getBlock(int x, int y, int z, uint8 *type, uint8 *meta){
#ifdef MSDBG
  printf("getBlock(x=%d, y=%d, z=%d)\n", x, y, z);
#endif
 
  if ((y < 0) || (y > 127))
  {
    LOG("Invalid y value (getBlock)");
    return false;
  }
 
  int chunk_x = ((x<0) ? (((x+1)/16)-1) : (x/16));
  int chunk_z = ((z<0) ? (((z+1)/16)-1) : (z/16));
 
  uint32 mapId;
  Map::posToId(chunk_x, chunk_z, &mapId);
 
  NBT_struct *chunk = getMapData(chunk_x, chunk_z);
 
  if(!chunk)
  {
    LOG("Loading chunk failed (getBlock)");
    return false;
  }
 
  int chunk_block_x = ((x<0) ? (15+((x+1)%16)) : (x%16));
  int chunk_block_z = ((z<0) ? (15+((z+1)%16)) : (z%16));
 
  uint8 *blocks = chunk->blocks;
  uint8 *metapointer = chunk->data;
  int index = y + (chunk_block_z * 128) + (chunk_block_x * 128 * 16);
  *type = blocks[index];
  uint8 metadata = metapointer[(index)>>1];
 
  if(y%2)
  {
    metadata&=0xf0;
    metadata>>=4;
  }
  else
  {
    metadata&=0x0f;
  }
 
  *meta = metadata;
  mapLastused[mapId] = (int)time(0);
 
  return true;
}
 
bool Map::getBlockLight(int x, int y, int z, uint8 *blocklight, uint8 *skylight)
{
#ifdef MSDBG
  printf("getBlockLight(x=%d, y=%d, z=%d)\n", x, y, z);
#endif
 
  if ((y < 0) || (y > 127))
  {
    LOG("Invalid y value (getBlockLight)");
    return false;
  }
 
  // Map chunk pos from block pos
  int chunk_x = ((x<0) ? (((x+1)/16)-1) : (x/16));
  int chunk_z = ((z<0) ? (((z+1)/16)-1) : (z/16));
 
  NBT_struct *chunk = getMapData(chunk_x, chunk_z);
 
  if(!chunk)
  {
    LOG("Loading chunk failed (getBlockLight)");
    return false;
  }
 
  // Which block inside the chunk
  int chunk_block_x = ((x<0) ? (15+((x+1)%16)) : (x%16));
  int chunk_block_z = ((z<0) ? (15+((z+1)%16)) : (z%16));
 
  uint8 *blocklightpointer=chunk->blocklight;
  uint8 *skylightpointer=chunk->skylight;
  int index=y + (chunk_block_z * 128) + (chunk_block_x * 128 * 16);
  *blocklight=blocklightpointer[(index)>>1];
  *skylight=skylightpointer[(index)>>1];
 
  if(y%2)
  {
    *blocklight&=0xf0;
    *blocklight>>=4;
 
    *skylight&=0xf0;
    *skylight>>=4;
  }
  else
  {
    *blocklight&=0x0f;
    *skylight&=0x0f;
  }
 
  return true;
}
 
bool Map::setBlockLight(int x, int y, int z, uint8 blocklight, uint8 skylight, uint8 setLight)
{
#ifdef MSDBG
  printf("setBlockLight(x=%d, y=%d, z=%d, %u, %u)\n", x, z, blocklight, skylight, setLight);
#endif
 
  if ((y < 0) || (y > 127))
  {
    LOG("Invalid y value (setBlockLight)");
    return false;
  }
 
  int chunk_x = ((x<0) ? (((x+1)/16)-1) : (x/16));
  int chunk_z = ((z<0) ? (((z+1)/16)-1) : (z/16));
 
  NBT_struct *chunk = getMapData(chunk_x, chunk_z);
 
  if(!chunk)
  {
    LOG("Loading chunk failed (setBlockLight)");
    return false;
  }
 
  int chunk_block_x = ((x<0) ? (15+((x+1)%16)) : (x%16));
  int chunk_block_z = ((z<0) ? (15+((z+1)%16)) : (z%16));
 
  uint8 *blocklightpointer = chunk->blocklight;
  uint8 *skylightpointer = chunk->skylight;
  int index = y + (chunk_block_z * 128) + (chunk_block_x * 128 * 16);
  char skylight_local = skylightpointer[index>>1];
  char blocklight_local = blocklightpointer[index>>1];
 
  if(y % 2)
  {
    if(setLight & 0x6) // 2 or 4
    {
      skylight_local &= 0x0f;
      skylight_local |= skylight<<4;
    }
 
    if(setLight & 0x5) // 1 or 4
    {
      blocklight_local &= 0x0f;
      blocklight_local |= blocklight<<4;
    }
  }
  else
  {
    if(setLight & 0x6) // 2 or 4
    {
      skylight_local &= 0xf0;
      skylight_local |= skylight;
    }
 
    if(setLight & 0x5) // 1 or 4
    {
      blocklight_local &= 0xf0;
      blocklight_local |= blocklight;
    }
  }
 
  if(setLight & 0x6) // 2 or 4
  {
    skylightpointer[index>>1] = skylight_local;
  }
 
  if(setLight & 0x5) // 1 or 4
  {
    blocklightpointer[index>>1] = blocklight_local;
  }
 
  return true;
}
 
bool Map::setBlock(int x, int y, int z, char type, char meta)
{
#ifdef MSDBG
  printf("setBlock(x=%d, y=%d, z=%d, type=%d, char=%d)\n", x, y, z, type, meta);
#endif
 
  if ((y < 0) || (y > 127))
  {
    LOG("Invalid y value (setBlock)");
    return false;
  }
 
  // Map chunk pos from block pos
  int chunk_x = ((x<0) ? (((x+1)/16)-1) : (x/16));
  int chunk_z = ((z<0) ? (((z+1)/16)-1) : (z/16));
 
  uint32 mapId;
  Map::posToId(chunk_x, chunk_z, &mapId);
 
  NBT_struct *chunk = getMapData(chunk_x, chunk_z);
 
  if(!chunk)
  {
    LOG("Loading chunk failed (setBlock)");
    return false;
  }
 
  // Which block inside the chunk
  int chunk_block_x = ((x<0) ? (15+((x+1)%16)) : (x%16));
  int chunk_block_z = ((z<0) ? (15+((z+1)%16)) : (z%16));
 
  uint8 *blocks = chunk->blocks;
  uint8 *metapointer = chunk->data;
  int index = y + (chunk_block_z * 128) + (chunk_block_x * 128 * 16);
  blocks[index] = type;
  char metadata = metapointer[index>>1];
 
  if(y%2)
  {
    metadata &= 0x0f;
    metadata |= meta<<4;
  }
  else
  {
    metadata &= 0xf0;
    metadata |= meta;
  }
  metapointer[index >> 1] = metadata;
 
  mapChanged[mapId] = 1;
  mapLastused[mapId] = (int)time(0);
 
  return true;
}
 
bool Map::sendBlockChange(int x, int y, int z, char type, char meta)
{
#ifdef MSDBG
  printf("sendBlockChange(x=%d, y=%d, z=%d, type=%d, meta=%d)\n", x, y, z, type, meta);
#endif
 
    uint8 curpos=0;
    uint8 changeArray[12];
    changeArray[0]=0x35; // Block change package
    curpos=1;
    putSint32(&changeArray[curpos], x);
    curpos+=4;
    changeArray[curpos]=y;
    curpos++;
    putSint32(&changeArray[curpos], z);
    curpos+=4;
    changeArray[10]=type;  // Replace block with
    changeArray[11]=meta;  // Metadata
 
    // TODO: only send to users in range
    for(unsigned int i=0;i<Users.size();i++)
    {
      bufferevent_write(Users[i]->buf_ev, &changeArray[0], 12);
    }
 
    return true;
}
 
bool Map::sendPickupSpawn(spawnedItem item)
{
  uint8 curpos=0;
  uint8 changeArray[23];
  changeArray[curpos]=0x15; // Pickup Spawn
  curpos++;
  putSint32(&changeArray[curpos], item.EID);
  curpos+=4;
  putSint16(&changeArray[curpos], item.item);
  curpos+=2;
  changeArray[curpos]=item.count;
  curpos++;
 
  putSint32(&changeArray[curpos], item.x);
  curpos+=4;
  putSint32(&changeArray[curpos], item.y);
  curpos+=4;
  putSint32(&changeArray[curpos], item.z);
  curpos+=4;
  changeArray[curpos]=0; // Rotation
  curpos++;
  changeArray[curpos]=0; // Pitch
  curpos++;
  changeArray[curpos]=0; // Roll
  curpos++;
 
  // TODO: only send to users in range
  for(unsigned int i=0;i<Users.size();i++)
  {
    bufferevent_write(Users[i]->buf_ev, &changeArray[0], 23);
  }
 
  return true;
}
 
bool Map::loadMap(int x, int z)
{
#ifdef MSDBG
  printf("loadMap(x=%d, z=%d)\n", x, z);
#endif
 
  uint32 mapId;
  Map::posToId(x, z, &mapId);
 
  // Generate map file name
 
  int mapposx=x;
  int modulox=(mapposx);
  while(modulox<0) modulox+=64;
  modulox%=64;
 
  int mapposz=z;
  int moduloz=(mapposz);
  while(moduloz<0) moduloz+=64;
  moduloz%=64;
 
  std::string infile=mapDirectory+"/"+base36_encode(modulox)+"/"+base36_encode(moduloz)+"/c."+base36_encode(mapposx)+"."+base36_encode(mapposz)+".dat";
 
  struct stat stFileInfo;
  if(stat(infile.c_str(), &stFileInfo) != 0)
  {
    LOG("File not found: " + infile);
    return false;
  }
 
  // Read gzipped map file
  gzFile mapfile=gzopen(infile.c_str(), "rb");
  uint8 uncompressedData[200000];
  gzread(mapfile, &uncompressedData[0], 200000);
  gzclose(mapfile);
 
  // Save this map data to map manager
  NBT_struct newMapStruct;
  TAG_Compound(&uncompressedData[0], &newMapStruct, true);
 
  maps[mapId] = newMapStruct;
 
  maps[mapId].x = x;
  maps[mapId].z = z;
 
  maps[mapId].blocks = get_NBT_pointer(&maps[mapId], "Blocks");
  maps[mapId].data = get_NBT_pointer(&maps[mapId], "Data");
  maps[mapId].blocklight = get_NBT_pointer(&maps[mapId], "BlockLight");
  maps[mapId].skylight = get_NBT_pointer(&maps[mapId], "SkyLight");
  // Check if the items were not found
  if(maps[mapId].blocks      == 0 ||
     maps[mapId].data        == 0 ||
     maps[mapId].blocklight  == 0 ||
     maps[mapId].skylight    == 0)
  {
    LOG("Error in map data");
    return false;
  }
 
  // Update last used time
  mapLastused[mapId] = (int)time(0);
 
  // Not changed
  mapChanged[mapId] = 0;
 
  return true;
}
 
bool Map::saveMap(int x, int z)
{
#ifdef MSDBG
  printf("saveMap(x=%d, z=%d)\n", x, z);
#endif
 
  uint32 mapId;
  Map::posToId(x, z, &mapId);
 
  if(!mapChanged[mapId])
    return true;
 
  if (!maps.count(mapId))
    return false;
 
  // Recalculate light maps
  generateLightMaps(x, z);
 
  // Generate map file name
 
  int mapposx=x;
  int modulox=(mapposx);
  while(modulox<0) modulox+=64;
  modulox%=64;
 
  int mapposz=z;
  int moduloz=(mapposz);
  while(moduloz<0) moduloz+=64;
  moduloz%=64;
 
  std::string outfile=mapDirectory+"/"+base36_encode(modulox)+"/"+base36_encode(moduloz)+"/c."+base36_encode(mapposx)+"."+base36_encode(mapposz)+".dat";
 
  // Try to create parent directories if necessary
  struct stat stFileInfo;
  if (stat(outfile.c_str(), &stFileInfo) != 0)
  {
    std::string outdir_a = mapDirectory+"/"+base36_encode(modulox);
    std::string outdir_b = mapDirectory+"/"+base36_encode(modulox)+"/"+base36_encode(moduloz);
 
    if (stat(outdir_b.c_str(), &stFileInfo) != 0)
    {
      if (stat(outdir_a.c_str(), &stFileInfo) != 0)
      {
#ifdef WIN32
        if (mkdir(outdir_a.c_str()) == -1)
#else
        if (mkdir(outdir_a.c_str(), 0755) == -1)
#endif
        {
          return false;
        }
      }
 
#ifdef WIN32
      if (mkdir(outdir_b.c_str()) == -1)
#else
      if (mkdir(outdir_b.c_str(), 0755) == -1)
#endif
      {
        return false;
      }
    }
  }
 
  uint8 uncompressedData[200000];
  int dumpsize=dumpNBT_struct(&maps[mapId].compounds[0], &uncompressedData[0]);
  gzFile mapfile2=gzopen(outfile.c_str(), "wb");
  gzwrite(mapfile2, &uncompressedData[0], dumpsize);
  gzclose(mapfile2);
 
  // Set "not changed"
  mapChanged[mapId] = 0;
 
  return true;
}
 
bool Map::releaseMap(int x, int z)
{
  // save first
  saveMap(x, z);
 
  uint32 mapId;
  Map::posToId(x, z, &mapId);
 
  mapChanged.erase(mapId);
  mapLastused.erase(mapId);
  if (maps.count(mapId))
    freeNBT_struct(&maps[mapId]);
 
  return maps.erase(mapId)?true:false;
}
 
// Send chunk to user
void Map::sendToUser(User *user, int x, int z)
{
#ifdef MSDBG
  printf("sendToUser(x=%d, z=%d)\n", x, z);
#endif
 
  uint32 mapId;
  Map::posToId(x, z, &mapId);
 
  uint8 data4[18+81920];
  uint8 mapdata[81920]={0};
  int mapposx=x;
  int mapposz=z;
 
  if(loadMap(x, z))
  {
    // Pre chunk
    data4[0]=0x32;
    putSint32(&data4[1], mapposx);
    putSint32(&data4[5], mapposz);
    data4[9]=1; // Init chunk
    bufferevent_write(user->buf_ev, (uint8 *)&data4[0], 10);
 
    // Chunk
    data4[0]=0x33;
 
    data4[11]=15;  // Size_x
    data4[12]=127; // Size_y
    data4[13]=15;  // Size_z
 
    memcpy(&mapdata[0], maps[mapId].blocks, 32768);
    memcpy(&mapdata[32768], maps[mapId].data, 16384);
    memcpy(&mapdata[32768+16384], maps[mapId].blocklight, 16384);
    memcpy(&mapdata[32768+16384+16384], maps[mapId].skylight, 16384);
 
    putSint32(&data4[1], mapposx*16);
    data4[5]=0;
    data4[6]=0;
    putSint32(&data4[7], mapposz*16);
 
    uLongf written=81920;
 
    // Compress data with zlib deflate
    compress((uint8 *)&data4[18], &written, (uint8 *)&mapdata[0], 81920);
 
    putSint32(&data4[14], written);
    bufferevent_write(user->buf_ev, (uint8 *)&data4[0], 18+written);
  }
}
mineserver.cpp
C++
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
#include <stdlib.h>
#ifdef WIN32
  #define _CRTDBG_MAP_ALLOC
  #include <crtdbg.h>
  #include <conio.h>
  #include <winsock2.h>
#else
  #include <sys/socket.h>
  #include <netinet/in.h>
  #include <arpa/inet.h>
  #include <string.h>
#endif
 
#include <sys/types.h>
#include <fcntl.h>
#include <cstdio>
#include <deque>
#include <iostream>
#include <event.h>
#include <ctime>
#include <vector>
 
#include "constants.h"
 
#include "logger.h"
 
#include "sockets.h"
#include "tools.h"
#include "map.h"
#include "user.h"
#include "chat.h"
#include "config.h"
#include "nbt.h"
#include <zlib.h>
 
#ifdef WIN32
static bool quit = false;
#endif
 
int setnonblock(int fd)
{
  #ifdef WIN32
  u_long iMode = 1;
  ioctlsocket(fd, FIONBIO, &iMode);
  #else
  int flags;
 
  flags = fcntl(fd, F_GETFL);
  flags |= O_NONBLOCK;
  fcntl(fd, F_SETFL, flags);
  #endif
 
  return 1;
}
 
int main(void)
{
  uint32 starttime=(uint32)time(0);
  uint32 tick=(uint32)time(0);
 
  Chat::get().loadAdmins(ADMINFILE);
  Chat::get().checkMotd(MOTDFILE);
 
  Conf::get().load(CONFIGFILE);
 
  Map::get().initMap();
  //Try to load port from config
  int port=atoi(Conf::get().value("port").c_str());
  //If failed, use default
  if(port==0)
    port=DEFAULT_PORT;
 
#ifdef WIN32
  _CrtSetDbgFlag ( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF );
  _CrtSetReportMode( _CRT_ERROR, _CRTDBG_MODE_DEBUG );
  WSADATA wsaData;
  int iResult;
  // Initialize Winsock
  iResult = WSAStartup(MAKEWORD(2,2), &wsaData);
  if (iResult != 0) {
    printf("WSAStartup failed with error: %d\n", iResult);
    return 1;
  }
#endif
 
  int socketlisten;
  struct sockaddr_in addresslisten;
  struct event accept_event;
  int reuse = 1;
 
  event_base *eventbase=(event_base *)event_init();
#ifdef WIN32
  socketlisten = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
#else
  socketlisten = socket(AF_INET, SOCK_STREAM, 0);
#endif
 
  if (socketlisten < 0)
  {
    fprintf(stderr,"Failed to create listen socket\n");
    return 1;
  }
 
  memset(&addresslisten, 0, sizeof(addresslisten));
 
  addresslisten.sin_family = AF_INET;
  addresslisten.sin_addr.s_addr = INADDR_ANY;
  addresslisten.sin_port = htons(port);
 
  //Bind to port
  if (bind(socketlisten, (struct sockaddr *)&addresslisten, sizeof(addresslisten)) < 0)
  {
    fprintf(stderr, "Failed to bind\n");
    return 1;
  }
 
  if (listen(socketlisten, 5) < 0)
  {
    fprintf(stderr, "Failed to listen to socket\n");
    return 1;
  }
 
  setsockopt(socketlisten, SOL_SOCKET, SO_REUSEADDR, (char *)&reuse, sizeof(reuse));
  setnonblock(socketlisten);
  event_set(&accept_event, socketlisten, EV_READ|EV_PERSIST, accept_callback, NULL);
  event_add(&accept_event, NULL);
 
  std::cout << std::endl
            << "   _____  .__  "                                                              << std::endl
            << "  /     \\ |__| ____   ____   ______ ______________  __ ___________ "         << std::endl
            << " /  \\ /  \\|  |/    \\_/ __ \\ /  ___// __ \\_  __ \\  \\/ // __ \\_  __ \\" << std::endl
            << "/    Y    \\  |   |  \\  ___/ \\___ \\\\  ___/|  | \\/\\   /\\  ___/|  | \\/" << std::endl
            << "\\____|__  /__|___|  /\\___  >____  >\\___  >__|    \\_/  \\___  >__|   "     << std::endl
            << "        \\/        \\/     \\/     \\/     \\/                 \\/       "    << std::endl
            << "Version " << VERSION <<" by Fador & Psoden"                                   << std::endl << std::endl;
 
  timeval loopTime;
  loopTime.tv_sec=1;
  loopTime.tv_usec=0;
 
  event_base_loopexit(eventbase,&loopTime);
  while (event_base_loop(eventbase, 0)==0)
  {
    if(time(0)-starttime>10)
    {
      starttime=(uint32)time(0);
      //Logger::get().log("Currently " + h.GetCount()-1 + " users in!");
      std::cout << "Currently " << Users.size() << " users in!" << std::endl;
 
      //If users, ping them
      if(Users.size()>0)
      {
        //0x00 package
        uint8 data=0;
        Users[0]->sendAll(&data, 1);
 
        //Send server time (after dawn)
        uint8 data3[9]={0x04, 0x00, 0x00, 0x00,0x00,0x00,0x00,0x0e,0x00};
        Users[0]->sendAll((uint8 *)&data3[0], 9);
      }
 
      //Try to load port from config
      int map_release_time=atoi(Conf::get().value("map_release_time").c_str());
      //If failed, use default
      if(map_release_time==0) map_release_time=DEFAULT_MAP_RELEASE_TIME;
 
      //Release chunks not used in <map_release_time> seconds
      std::vector<uint32> toRelease;
      for (std::map<uint32, int>::const_iterator it = Map::get().mapLastused.begin(); it != Map::get().mapLastused.end(); ++it)
      {
        if(Map::get().mapLastused[it->first] <= time(0)-map_release_time)
        {
          toRelease.push_back(it->first);
        }
      }
 
      int x_temp,z_temp;
      for(unsigned i=0;i<toRelease.size();i++)
      {
        Map::get().idToPos(toRelease[i], &x_temp,&z_temp);
        Map::get().releaseMap(x_temp,z_temp);
      }
    }
 
    //Every second
    if(time(0)-tick>0)
    {
      tick=(uint32)time(0);
      //Loop users
      for(unsigned int i=0;i<Users.size();i++)
      {
        //for(uint8 j=0;j<10;j++)
        {
          //Push new map data
          Users[i]->pushMap();
        }
        //for(uint8 j=0;j<20;j++)
        {
          //Remove map far away
          Users[i]->popMap();
        }
      }
    }
#ifdef WIN32
    if(_kbhit())
        quit = 1;
#endif
 
    event_base_loopexit(eventbase,&loopTime);
  }
 
  Map::get().freeMap();
 
  //event_dispatch();
 
#ifdef WIN32
  closesocket(socketlisten);
#else
  close(socketlisten);
#endif
 
  //Windows debug
#ifdef WIN32
  _CrtDumpMemoryLeaks();
#endif
 
  return EXIT_SUCCESS;
}
0
0 / 0 / 0
Регистрация: 07.11.2010
Сообщений: 7
07.11.2010, 16:31  [ТС]
sockets.cpp
C++
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
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
#ifdef WIN32
    #define _CRTDBG_MAP_ALLOC
    #include <stdlib.h>
    #include <crtdbg.h>
    #include <conio.h>
    #include <winsock2.h>
typedef  int socklen_t;
 
#else
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#endif
 
#include <iostream>
#include <fstream>
#include <deque>
#include <fstream>
#include <vector>
#include <ctime>
#include <event.h>
#include <sys/stat.h> 
#include "logger.h"
#include "constants.h"
 
#include "tools.h"
#include <zlib.h>
#include "user.h"
#include "map.h"
#include "chat.h"
#include "nbt.h"
 
extern int setnonblock(int fd);
 
void buf_write_callback(struct bufferevent *bev, void *arg)
{
}
 
void buf_error_callback(struct bufferevent *bev, short what, void *arg)
{
  User *client = (User *)arg;
  bufferevent_free(client->buf_ev);
 
#ifdef WIN32
  closesocket(client->fd);
#else
  close(client->fd);
#endif
 
  remUser(client->fd);
}
 
void buf_read_callback(struct bufferevent *incoming, void *arg)
{
  uint32 i = 0;
 
  User *user=(User *)arg;
 
  int read = 1;
 
  uint8 *buf = new uint8[2048];
 
  //Push data to buffer
  while(read)
  {
    if((read = bufferevent_read(incoming, buf, 2048)))
    {
      for(int i = 0;i<read;i++)
      {
        user->buffer.push_back(buf[i]);
      }
    }
  }
 
  delete [] buf;
 
  while(user->buffer.size()>0)
  {
    // If not waiting more data
    if(!user->waitForData)
    {
      user->action = user->buffer.front();
      user->buffer.pop_front();
      //printf("Action: 0x%x\n", user->action);
    }
    else
    {
       user->waitForData = false;
    }
 
    // Keep Alive ([url]http://mc.kev009.com/wiki/Protocol#Keep_Alive_.280x00.29[/url])
    if(user->action == 0x00)
    {  
      //Ping
    }
 
    // Login request ([url]http://mc.kev009.com/wiki/Protocol#Login_Request_.280x01.29[/url])
    else if(user->action == 0x01)
    {    
      //Check that we have enought data in the buffer
      if(user->buffer.size()<12)
      {
        user->waitForData = true;
        return;
      }
      uint32 curpos = 0;
      
      //Client protocol version
      uint8 tmpIntArray[4] = {0};
      for(i = 0;i<4;i++) tmpIntArray[i]=user->buffer[curpos+i]; 
      int version = getUint32(&tmpIntArray[0]);     
      curpos+=4;
 
      //Player name length
      uint8 tmpShortArray[2] = {0};
      for(i = 0;i<2;i++) tmpShortArray[i]=user->buffer[curpos+i]; 
      int len = getUint16(&tmpShortArray[0]);     
      curpos+=2;
 
      //Check for data
      if(user->buffer.size()<curpos+len+2)
      {
        user->waitForData = true;
        return;
      }
 
      std::string player;
      //Read player name
      for(int pos = 0;pos<len;pos++)
      {
        player+=user->buffer[curpos+pos];
      }
      curpos+=len;
 
    
      //Password length
      for(i = 0;i<2;i++) tmpShortArray[i]=user->buffer[curpos+i]; 
      len = getUint16(&tmpShortArray[0]);     
      curpos+=2;
    
      std::string passwd;
      //Check for data
      if(user->buffer.size()<curpos+len)
      {
        user->waitForData = true;
        return;
      }
 
      //Read password
      for(int pos = 0;pos<len;pos++)
      {
        passwd += user->buffer[curpos+pos];
      }
      curpos+=len;
 
      //Package completely received, remove from buffer
      user->buffer.erase(user->buffer.begin(), user->buffer.begin()+curpos);
 
      std::cout << "Player " << user->UID << " login v." <<version<<" : " << player <<":" << passwd << std::endl;
      if(version == 2 || version == 3)
      {        
        //Login OK package
        char data[9]={0x01, 0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00};
        putSint32((uint8 *)&data[1],user->UID);
        bufferevent_write(user->buf_ev, (char *)&data[0], 9);
 
        //Send server time (after dawn)
        uint8 data3[9]={0x04, 0x00, 0x00, 0x00,0x00,0x00,0x00,0x0e,0x00};
        bufferevent_write(user->buf_ev, (char *)&data3[0], 9);
 
        //Inventory
        uint8 data4[7+36*5];
        data4[0]=0x05;
        putSint32(&data4[1],-1);
        data4[5]=0;
        data4[6]=36;
        for(i = 0;i<36;i++)
        {
          if(i<10)
            putSint16(&data4[7+i*5], 0x115); //Diamond shovel
          else if(i<20)
            putSint16(&data4[7+i*5], 50); //Torch
          else
            putSint16(&data4[7+i*5], 1); //Stone
 
          data4[7+2+i*5]=1; //Count
          putSint16(&data4[7+3+i*5], 0);
        }
        bufferevent_write(user->buf_ev, (char *)&data4[0], 7+36*5);
 
        data4[6]=4;
        putSint32(&data4[1],-2);
        bufferevent_write(user->buf_ev, (char *)&data4[0], 7+4*5);
 
        putSint32(&data4[1],-3);
        bufferevent_write(user->buf_ev, (char *)&data4[0], 7+4*5);
            
        user->changeNick(player, Chat::get().admins);
       
        // Send motd
        std::ifstream motdfs( MOTDFILE.c_str() );
        
        std::string temp;
 
        while( getline( motdfs, temp ) ) {
          // If not commentline
          if(temp[0] != COMMENTPREFIX) {
            Chat::get().sendMsg(user, temp, USER);
          }
        }
        motdfs.close();
 
        //Teleport player
        user->teleport(Map::get().spawnPos.x,Map::get().spawnPos.y+2,Map::get().spawnPos.z);
 
        //Put nearby chunks to queue
        for(int x=-user->viewDistance;x<=user->viewDistance;x++)
        {
          for(int z=-user->viewDistance;z<=user->viewDistance;z++)
          {
            user->addQueue(Map::get().spawnPos.x/16+x,Map::get().spawnPos.z/16+z);
          }
        }
        // Push chunks to user
        user->pushMap();
 
        //Spawn this user to others
        user->spawnUser(Map::get().spawnPos.x*32,(Map::get().spawnPos.y+2)*32,Map::get().spawnPos.z*32);
        //Spawn other users for connected user
        user->spawnOthers();
        
                          
        //Send "On Ground" signal
        char data6[2]={0x0A, 0x01};
        bufferevent_write(user->buf_ev, (char *)&data6[0], 2);
 
        user->logged = true;
 
        Chat::get().sendMsg(user, player+" connected!", ALL);
 
      }
      else
      {
        bufferevent_free(user->buf_ev);
        #ifdef WIN32
          closesocket(user->fd);
        #else
          close(user->fd);
        #endif
        remUser(user->fd);
      }    
 
    }
 
    // Handshake
    else if(user->action == 0x02)
    {
      if(user->buffer.size()<3)
      {
        user->waitForData = true;
        return;
      }
      int curpos = 0;
 
      //Player name length
      uint8 tmpShortArray[2] = {0};
      for(i = 0;i<2;i++) tmpShortArray[i]=user->buffer[curpos+i]; 
      int len = getSint16(&tmpShortArray[0]);     
      curpos+=2;
 
      //Check for data
      if(user->buffer.size()<(unsigned int)curpos+len)
      {
        user->waitForData = true;
        return;
      }
 
      //Read player name
      std::string player;
      for(int pos = 0;pos<len;pos++)
      {
         player += user->buffer[curpos+pos];
      }
      curpos+=len;
 
      //Remove package from buffer
      user->buffer.erase(user->buffer.begin(), user->buffer.begin()+curpos);
      std::cout << "Handshake player: " << player << std::endl;
 
      //char data[9]={0x01, 0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00};    
      //bufferevent_write(user->buf_ev, (char *)&data[0], 9); 
      //char data2[19]={0x02, 0x00,0x10,0x32 ,0x65 ,0x36 ,0x36 ,0x66 ,0x31 ,0x64 ,0x63 ,0x30 ,0x33 ,0x32 ,0x61 ,0x62,0x35 ,0x66 ,0x30};    
      //bufferevent_write(user->buf_ev, (char *)&data2[0], 19);
 
      //Send handshake package
      char data2[4]={0x02, 0x00,0x01,'-'};    
      bufferevent_write(user->buf_ev, (char *)&data2[0], 4);
 
      //user->logged = 1;
      //user->changeNick(player);
      //char data3[5]={0x1e, 0x01, 0x02, 0x03, 0x04};
      //bufferevent_write(user->buf_ev, (char *)&data3[0], 5);
    } 
 
    // Chat
    else if(user->action == 0x03)
    {
      // Wait for length-short. HEHE
      if(user->buffer.size()<2)
      {
        user->waitForData = true;
        return;
      }
      
      int curpos = 0;
      
      uint8 tmpLenArray[2] = {0};
      for(i = 0;i<2;i++) tmpLenArray[i]=user->buffer[curpos+i]; 
      short len = getSint16(&tmpLenArray[0]); 
      curpos+=2;
      
      // Wait for whole message
      if(user->buffer.size()<(unsigned int)curpos+len)
      {
        user->waitForData = true;
        return;
      }
      
      //Read message
      std::string msg;
      for(i = 0;i<(unsigned int)len;i++) msg += user->buffer[curpos+i];
      
      curpos += len;
      
      // Remove from buffer
      user->buffer.erase(user->buffer.begin(), user->buffer.begin()+curpos);
 
      Chat::get().handleMsg( user, msg );
 
    }
 
    // Inventory change
    else if(user->action == 0x05)
    {
 
      if(user->buffer.size()<14)
      {
        user->waitForData = true;
        return;
      }
 
      int curpos = 0;
 
      //Read inventory type (-1,-2 or -3)
      uint8 tmpIntArray[4] = {0};
      for(i = 0;i<4;i++) tmpIntArray[i]=user->buffer[curpos+i]; 
      int type = getSint32(&tmpIntArray[0]);
      curpos+=4;
 
      uint8 tmpShortArray[2] = {0};
      for(i = 0;i<2;i++) tmpShortArray[i]=user->buffer[curpos+i]; 
      //int count = getSint16(&tmpShortArray[0]);     
      curpos+=2;
 
      int items = 0;
 
      switch(type)
      {
        //Main inventory
        case -1:
          items = 36;
        break;
 
        //Equipped armour
        case -2:
          items = 4;
        break;
 
        //Crafting slots
        case -3:
          items = 4;
        break;
      }
 
      if(user->buffer.size()<(unsigned int)6+2*items)
      {
        user->waitForData = true;
        return;
      }
 
      for(i = 0;i<(unsigned int)items;i++)
      {
        int j = 0;
        for(j = 0;j<2;j++) tmpShortArray[j]=user->buffer[curpos+j]; 
        int item_id = getSint16(&tmpShortArray[0]);     
        curpos+=2;
 
        if(user->buffer.size()<curpos+(items-i-1)*2)
 
        {
          user->waitForData = true;
          return;
        }
        
        if(item_id!=-1)
        {
          if(user->buffer.size()-curpos<(items-i-1)*2+3)
          {
            user->waitForData = true;
            return;
          }
 
          //uint8 numberOfItems = user->buffer[curpos];
          curpos++;
          
          for(j = 0;j<2;j++) tmpShortArray[j]=user->buffer[curpos+j]; 
          //int health = getSint16(&tmpShortArray[0]);     
          curpos+=2;
        }
      }
 
      //std::cout << "Got items type " << type << std::endl;
      //Package completely received, remove from buffer
      user->buffer.erase(user->buffer.begin(), user->buffer.begin()+curpos);
 
    }
 
    // Player ([url]http://mc.kev009.com/wiki/Protocol#Player_.280x0A.29[/url])
    else if(user->action == 0x0a)
    {
      if(user->buffer.size()<1)
      {
        user->waitForData = true;
        return;
      }      
      user->buffer.erase(user->buffer.begin(), user->buffer.begin()+1);
    }
    else if(user->action == 0x0b) // PLayer position
    {
      if(user->buffer.size()<33)
      {
        user->waitForData = true;
        return;
      }
      int curpos = 0;
      double x,y,stance,z;
      uint8 doublearray[8];
 
      //Read double X
      for(i = 0;i<8;i++) doublearray[i]=user->buffer[curpos+i];
      x = getDouble(&doublearray[0]);    
      curpos+=8;
 
      //Read double Y
      for(i = 0;i<8;i++) doublearray[i]=user->buffer[curpos+i];
      y = getDouble(&doublearray[0]);
      curpos+=8;
 
      //Read double stance
      for(i = 0;i<8;i++) doublearray[i]=user->buffer[curpos+i];
      stance = getDouble(&doublearray[0]);
      curpos+=8;
 
      //Read double Z
      for(i = 0;i<8;i++) doublearray[i]=user->buffer[curpos+i];
      z = getDouble(&doublearray[0]);
      curpos+=8;
 
      user->updatePos(x, y, z, stance);
 
      //Skip others
      user->buffer.erase(user->buffer.begin(), user->buffer.begin()+33);
    }
    else if(user->action == 0x0c) //Player Look
    {
      if(user->buffer.size()<9)
      {
        user->waitForData = true;
        return;
      }
 
      float yaw,pitch;
      uint8 onground;
      uint8 tmpFloatArray[4] = {0};
      int curpos = 0;
      
      for(i = 0;i<4;i++) tmpFloatArray[i]=user->buffer[curpos+i]; 
      yaw = getFloat(&tmpFloatArray[0]);     
      curpos+=4;
      
      for(i = 0;i<4;i++) tmpFloatArray[i]=user->buffer[curpos+i]; 
      pitch = getFloat(&tmpFloatArray[0]);     
      curpos+=4;
      
      user->updateLook(yaw, pitch);
 
      onground = user->buffer[curpos];
      curpos++;
 
      user->buffer.erase(user->buffer.begin(), user->buffer.begin()+9);
    }
    else if(user->action == 0x0d) //Player Position & Look
    {
      if(user->buffer.size()<41)
      {
        user->waitForData = true;
        return;
      }
      int curpos = 0;
 
      double x,y,stance,z;
      uint8 doublearray[8];
 
      //Read double X
      for(i = 0;i<8;i++) doublearray[i]=user->buffer[curpos+i];
      x = getDouble(&doublearray[0]);    
      curpos+=8;
 
      //Read double Y
      for(i = 0;i<8;i++) doublearray[i]=user->buffer[curpos+i];
      y = getDouble(&doublearray[0]);
      curpos+=8;
 
      //Read double stance
      for(i = 0;i<8;i++) doublearray[i]=user->buffer[curpos+i];
      stance = getDouble(&doublearray[0]);
      curpos+=8;
 
      //Read double Z
      for(i = 0;i<8;i++) doublearray[i]=user->buffer[curpos+i];
      z = getDouble(&doublearray[0]);
      curpos+=8;
 
 
      float yaw,pitch;
      uint8 tmpFloatArray[4] = {0};
      
      for(i = 0;i<4;i++) tmpFloatArray[i]=user->buffer[curpos+i]; 
      yaw = getFloat(&tmpFloatArray[0]);     
      curpos+=4;
      
      for(i = 0;i<4;i++) tmpFloatArray[i]=user->buffer[curpos+i]; 
      pitch = getFloat(&tmpFloatArray[0]);     
      curpos+=4;
 
      //Update user data
      user->updatePos(x, y, z, stance);
      user->updateLook(yaw, pitch);
      user->buffer.erase(user->buffer.begin(), user->buffer.begin()+41);
    }
    else if(user->action == 0x0e) //Player Digging
    {
      if(user->buffer.size()<11)
      {
        user->waitForData = true;
        return;
      }
      uint8 tmpIntArray[4];
      int curpos = 0;
      char status = user->buffer[curpos];
      curpos++;
 
      for(i = 0;i<4;i++) tmpIntArray[i]=user->buffer[curpos+i];      
      int x = getSint32(&tmpIntArray[0]);
      curpos+=4;
 
      char y = user->buffer[curpos];
      curpos++;
 
      for(i = 0;i<4;i++) tmpIntArray[i]=user->buffer[curpos+i];
      int z = getSint32(&tmpIntArray[0]);
      curpos+=4;
      user->buffer.erase(user->buffer.begin(), user->buffer.begin()+11);
      //If block broken
      if(status == 3)
      {
        uint8 block; uint8 meta;
        if(Map::get().getBlock(x,y,z, &block, &meta))
        {          
          Map::get().sendBlockChange(x,y,z,0,0);
          Map::get().setBlock(x,y,z,0,0);
 
          uint8 topblock; uint8 topmeta;        
          if(Map::get().getBlock(x,y+1,z, &topblock, &topmeta) && topblock == 0x4e) //If snow on top, destroy it
          {
            Map::get().sendBlockChange(x,y+1,z,0, 0);
            Map::get().setBlock(x,y+1,z,0,0);
          }
 
          if(block!=0x4e && (int)block>0 && (int)block<255)
          {         
            spawnedItem item;
            item.EID = generateEID();
            item.item=(int)block;
            item.x = x*32;
            item.y = y*32;
            item.z = z*32;
            item.x+=(rand()%32);
            item.z+=(rand()%32);
            Map::get().sendPickupSpawn(item);
          }
        }
      }
    }
    else if(user->action == 0x0f) //Player Block Placement
    {
      if(user->buffer.size()<12)
      {
        user->waitForData = true;
        return;
      }
      int curpos = 0;
      uint8 tmpShortArray[2];
      uint8 tmpIntArray[4];
      int orig_x,orig_y,orig_z;
      bool change = false;
 
      for(i = 0;i<2;i++) tmpShortArray[i]=user->buffer[curpos+i]; 
      int blockID = getSint16(&tmpShortArray[0]);
      curpos+=2;
 
      for(i = 0;i<4;i++) tmpIntArray[i]=user->buffer[curpos+i];      
      int x = orig_x = getSint32(&tmpIntArray[0]);
      curpos+=4;
 
      int y = orig_y = user->buffer[curpos];
      curpos++;
 
      for(i = 0;i<4;i++) tmpIntArray[i]=user->buffer[curpos+i];
      int z = orig_z = getSint32(&tmpIntArray[0]);
      curpos+=4;
 
      int direction = user->buffer[curpos];
 
 
      user->buffer.erase(user->buffer.begin(), user->buffer.begin()+12);
 
 
 
      uint8 block;
      uint8 metadata;
      Map::get().getBlock(x,y,z, &block, &metadata);
 
      switch(direction)        
      {
        case 0: y--; break;
        case 1: y++; break;
        case 2: z--; break;
        case 3: z++; break;
        case 4: x--; break;
        case 5: x++; break;
      }
      
      uint8 block_direction;
      uint8 metadata_direction;
      Map::get().getBlock(x,y,z, &block_direction, &metadata_direction);
 
 
      //If placing normal block and current block is empty
      if(blockID<0xff && blockID!=-1 && block_direction == 0x00)
      {
        change = true;
      }
 
      if(block == 0x4e || block == 50) //If snow or torch, overwrite
      {
        change = true;
        x = orig_x;
        y = orig_y;
        z = orig_z;
      }
 
      //Door status change
      if((block == 0x40)|| (block == 0x47))
      {
        change = true;
 
        blockID = block;
 
        //Toggle door state
        if(metadata&0x4)
        {
          metadata&=~0x4;
        }
        else
        {
          metadata|=0x4;
        }
 
        uint8 metadata2,block2;
 
        int modifier=(metadata&0x8)?1:-1;
                
        x = orig_x;
        y = orig_y;
        z = orig_z;
 
        Map::get().getBlock(x,y+modifier,z, &block2, &metadata2);
        if(block2 == block)
        {
          if(metadata2&0x4)
          {
            metadata2&=~0x4;
          }
          else
          {
            metadata2|=0x4;
          }
 
          Map::get().setBlock(x,y+modifier,z, block2, metadata2);
          Map::get().sendBlockChange(x,y+modifier,z,blockID, metadata2);
        }
 
      }
 
      if(change)
      {
        Map::get().setBlock(x,y,z, blockID, metadata);
        Map::get().sendBlockChange(x,y,z,blockID, metadata);
      }
 
    }
    else if(user->action == 0x10) //Holding change
    {
      if(user->buffer.size()<6)
      {
        user->waitForData = true;
        return;
      }
      int itemID = getUint16(&user->buffer[4]);      
      user->buffer.erase(user->buffer.begin(), user->buffer.begin()+6);
 
      //Send holding change to others
      uint8 holdingPackage[7];
      holdingPackage[0]=0x10;
      putSint32(&holdingPackage[1], user->UID);
      putSint16(&holdingPackage[5], itemID);
      user->sendOthers(&holdingPackage[0],7);
 
    }
    else if(user->action == 0x12) //Arm Animation
    {
      if(user->buffer.size()<5)
      {
        user->waitForData = true;
        return;
      }
      char forward = user->buffer[4];
      user->buffer.erase(user->buffer.begin(), user->buffer.begin()+5);
 
      uint8 animationPackage[6];
      animationPackage[0]=0x12;
      putSint32(&animationPackage[1],user->UID);
      animationPackage[5]=forward;
      user->sendOthers(&animationPackage[0], 6);
    }
    else if(user->action == 0x15) //Pickup Spawn
    {
      if(user->buffer.size()<22)
      {
        user->waitForData = true;
        return;
      }
      
      user->buffer.erase(user->buffer.begin(), user->buffer.begin()+22);
    }
    else if(user->action == 0xff) //Quit message
    {
      if(user->buffer.size()<2)
      {
        user->waitForData = true;
        return;
      }
      int curpos = 0;
      uint8 shortArray[2];
      for(i = 0;i<2;i++) shortArray[i]=user->buffer[i];
      int len = getSint16(&shortArray[0]);
 
      curpos+=2;
      // Wait for whole message
      if(user->buffer.size()<(unsigned int)curpos+len)
      {
        user->waitForData = true;
        return;
      }
      
      //Read message
      std::string msg;
      for(i = 0;i<(unsigned int)len;i++) msg += user->buffer[curpos+i];
 
      curpos+=len;
      user->buffer.erase(user->buffer.begin(), user->buffer.begin()+curpos);
 
      bufferevent_free(user->buf_ev);
      #ifdef WIN32
        closesocket(user->fd);
      #else
        close(user->fd);
      #endif
      remUser(user->fd);
    }
    else
    {
      printf("Unknown action: 0x%x\n", user->action);
      bufferevent_free(user->buf_ev);
      #ifdef WIN32
        closesocket(user->fd);
      #else
        close(user->fd);
      #endif
      remUser(user->fd);
    }
 
  } //End while
 
}
 
 
 
  //remUser(GetSocket());
void accept_callback(int fd,
                     short ev,
                     void *arg)
{
  int client_fd;
  struct sockaddr_in client_addr;
  socklen_t client_len = sizeof(client_addr);
  
 
  client_fd = accept(fd,
                     (struct sockaddr *)&client_addr,
                     &client_len);
  if (client_fd < 0)
    {
      LOG("Client: accept() failed");
      return;
    }
  User *client = addUser(client_fd,generateEID());
  setnonblock(client_fd);
 
  client->buf_ev = bufferevent_new(client_fd,
                                   buf_read_callback,
                                   buf_write_callback,
                                   buf_error_callback,
                                   client);
 
  bufferevent_enable(client->buf_ev, EV_READ);
}
user.cpp
C++
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
#include <vector>
#include <cstdlib>
#include <cstdio>
#include <iostream>
#include <deque>
#include <algorithm>
#include <sys/stat.h> 
#ifdef WIN32
  #include <winsock2.h>
#endif
#include "constants.h"
 
#include "logger.h"
 
#include "tools.h"
#include "map.h"
#include "user.h"
#include "nbt.h"
#include <zlib.h>
#include "chat.h"
 
 
std::vector<User *> Users;
 
 
User::User(int sock, uint32 EID)
{
  this->action=0;
  this->waitForData=false;
  this->fd=sock;
  this->UID=EID;
  this->logged=false;
  // ENABLED FOR DEBUG
  this->admin=true;
 
  this->pos.x=Map::get().spawnPos.x;
  this->pos.y=Map::get().spawnPos.y;
  this->pos.z=Map::get().spawnPos.z;
}
 
bool User::changeNick(std::string nick, std::deque<std::string> admins)
{
  this->nick=nick;
  
  // Check adminstatus
  for(unsigned int i=0;i<admins.size();i++) {
    if(admins[i] == nick) {
        this->admin=true;
        LOG(nick + " admin");
    }
  }      
  
  return true;
}
 
User::~User()
{
  if(this->nick.size())
  {
    //Send signal to everyone that the entity is destroyed
    uint8 entityData[5];
    entityData[0]=0x1d; //Destroy entity;
    putSint32(&entityData[1], this->UID);
    this->sendOthers(&entityData[0],5);
  }
}
 
// Kick player
bool User::kick(std::string kickMsg) 
{
  int len = kickMsg.size();
  uint8 *data = new uint8 [3+len];
  
  data[0] = 0xff;
  putSint16(&data[1],len);
  for(unsigned int i=0;i<kickMsg.size();i++) data[i+3]= kickMsg[i];
  
  bufferevent_write(this->buf_ev, data,len+3);
 
  delete [] data;
  return true;
}
 
bool User::updatePos(double x, double y, double z, double stance)
{
    if(nick.size() && logged)
    {
      //Do we send relative or absolute move values
      if(0)//abs(x-this->pos.x)<127
        //&& abs(y-this->pos.y)<127
        //&& abs(z-this->pos.z)<127)
      {
        uint8 movedata[8];
        movedata[0]=0x1f; //Relative move
        putUint32(&movedata[1],this->UID);
        movedata[5]=(char)(x-this->pos.x);
        movedata[6]=(char)(y-this->pos.y);
        movedata[7]=(char)(z-this->pos.z);
        this->sendOthers(&movedata[0],8);
      }
      else
      {          
        this->pos.x=x;
        this->pos.y=y;
        this->pos.z=z;
        this->pos.stance=stance;
        uint8 teleportData[19];
        teleportData[0]=0x22; //Teleport
        putSint32(&teleportData[1],this->UID);
        putSint32(&teleportData[5],(int)(this->pos.x*32));
        putSint32(&teleportData[9],(int)(this->pos.y*32));
        putSint32(&teleportData[13],(int)(this->pos.z*32));
        teleportData[17]=(char)this->pos.yaw;
        teleportData[18]=(char)this->pos.pitch;
        this->sendOthers(&teleportData[0],19);
      }
    
      //Chunk position changed, check for map updates
      if((int)(x/16) != curChunk.x ||(int)(z/16) != curChunk.z)
      {
        //This is not accurate chunk!!
        curChunk.x=(int)(x/16);
        curChunk.z=(int)(z/16);
 
        for(int mapx=-viewDistance+curChunk.x;mapx<=viewDistance+curChunk.x;mapx++)
        {
          for(int mapz=-viewDistance+curChunk.z;mapz<=viewDistance+curChunk.z;mapz++)
          {
            addQueue(mapx,mapz);
          }
        }
 
        for(unsigned int i=0;i<mapKnown.size();i++)
        {
          //If client has map data more than viesDistance+1 chunks away, remove it
          if(mapKnown[i].x<curChunk.x-viewDistance-1 ||
             mapKnown[i].x>curChunk.x+viewDistance+1 ||
             mapKnown[i].z<curChunk.z-viewDistance-1 ||
             mapKnown[i].z>curChunk.z+viewDistance+1)
          {
            addRemoveQueue(mapKnown[i].x,mapKnown[i].z);              
          }
        }
      }
    }
 
    this->pos.x=x;
    this->pos.y=y;
    this->pos.z=z;
    this->pos.stance=stance;
    return true;
}
 
bool User::updateLook(float yaw, float pitch)
{
  
    uint8 lookdata[7];
    lookdata[0]=0x20;
    putUint32(&lookdata[1],this->UID);
    lookdata[5]=(char)(yaw);
    lookdata[6]=(char)(pitch);          
    this->sendOthers(&lookdata[0],7);
      
    this->pos.yaw=yaw;
    this->pos.pitch=pitch;
    return true;
}
 
bool User::sendOthers(uint8* data,uint32 len)
{
  for(unsigned int i=0;i<Users.size();i++)
  {
    if(Users[i]->fd!=this->fd && Users[i]->logged)
    {
      bufferevent_write(Users[i]->buf_ev, data,len);
    }
  }
  return true;
}
 
bool User::sendAll(uint8* data,uint32 len)
{
  for(unsigned int i=0;i<Users.size();i++)
  {
    if(Users[i]->fd && Users[i]->logged)
    {
      bufferevent_write(Users[i]->buf_ev, data,len);
    }
  }
  return true;
}
 
bool User::addQueue(int x, int z)
{
  coord newMap={x,0,z};
 
  for(unsigned int i=0;i<mapQueue.size();i++)
  {
    // Check for duplicates
    if(mapQueue[i].x==newMap.x && mapQueue[i].z==newMap.z)
      return false;
  }
 
  for(unsigned int i=0;i<mapKnown.size();i++)
  {
    //Check for duplicates
    if(mapKnown[i].x==newMap.x && mapKnown[i].z==newMap.z)
      return false;
  }
 
  this->mapQueue.push_back(newMap);
 
  return true;
}
 
bool User::addRemoveQueue(int x, int z)
{
  coord newMap={x,0,z};
 
  this->mapRemoveQueue.push_back(newMap);
 
  return true;
}
 
bool User::addKnown(int x, int z)
{
  coord newMap={x,0,z};
  this->mapKnown.push_back(newMap);
 
  return true;
}
 
bool User::delKnown(int x, int z)
{
  
  for(unsigned int i=0;i<mapKnown.size();i++)
  {
    if(mapKnown[i].x==x && mapKnown[i].z==z)
    {
      mapKnown.erase(mapKnown.begin()+i);
      return true;
    }
  }
 
  return false;
}
 
bool SortVect(const coord &first, const coord &second)
{
  return (first.x-Map::get().spawnPos.x/16)*(first.x-Map::get().spawnPos.x/16)+(first.z-Map::get().spawnPos.z/16)*(first.z-Map::get().spawnPos.z/16) 
          < (second.x-Map::get().spawnPos.x/16)*(second.x-Map::get().spawnPos.x/16)+(second.z-Map::get().spawnPos.z/16)*(second.z-Map::get().spawnPos.z/16);
}
 
bool User::popMap()
{
  //If map in queue, push it to client
  while(this->mapRemoveQueue.size())
  {
    uint8 preChunk[10];
    //Pre chunk
    preChunk[0]=0x32;
    putSint32(&preChunk[1], mapRemoveQueue[0].x);
    putSint32(&preChunk[5], mapRemoveQueue[0].z);
    preChunk[9]=0; //Unload chunk
    bufferevent_write(this->buf_ev, (uint8 *)&preChunk[0], 10);
 
    //Delete from known list
    delKnown(mapRemoveQueue[0].x, mapRemoveQueue[0].z);
 
    //Remove from queue
    mapRemoveQueue.erase(mapRemoveQueue.begin());
 
    //return true;
  }
 
  return false;
}
 
bool User::pushMap()
{
  // If map in queue, push it to client
  while(this->mapQueue.size() > 0)
  {
    // Sort by distance from center
    sort(mapQueue.begin(),mapQueue.end(),SortVect);
 
    Map::get().sendToUser(this,mapQueue[0].x, mapQueue[0].z);
 
    // Add this to known list
    addKnown(mapQueue[0].x, mapQueue[0].z);
 
    // Remove from queue
    mapQueue.erase(mapQueue.begin());
  }
 
  return true;
}
 
bool User::teleport(double x, double y, double z)
{      
  uint8 teleportdata[42]={0};
  int curpos=0;
  teleportdata[curpos]=0x0d;
  curpos++;
  putDouble(&teleportdata[curpos],x); //X
  curpos+=8;
  putDouble(&teleportdata[curpos],y);  //Y
  curpos+=8;
  putDouble(&teleportdata[curpos], 0.0); //Stance
  curpos+=8;
  putDouble(&teleportdata[curpos],z); //Z
  curpos+=8;
 
  putFloat(&teleportdata[curpos], 0.0);
  curpos+=4;
  putFloat(&teleportdata[curpos], 0.0);
  curpos+=4;
  teleportdata[curpos] = 0; //On Ground
  bufferevent_write(this->buf_ev, (char *)&teleportdata[0], 42);
 
  //Also update pos for other players
  updatePos(x,y,z,0);
  return true;
}
 
bool User::spawnUser(int x, int y, int z)
{
   uint8 entityData2[256];
  int curpos=0;
  entityData2[curpos]=0x14; //Named Entity Spawn
  curpos++;
  putSint32(&entityData2[curpos], this->UID);        
  curpos+=4;
  entityData2[curpos]=0;
  entityData2[curpos+1]=this->nick.size();
  curpos+=2;
  
  for(unsigned int j=0;j<this->nick.size();j++)
  {
    entityData2[curpos]=this->nick[j];
    curpos++;
  }
  
  putSint32(&entityData2[curpos],x);
  curpos+=4;
  putSint32(&entityData2[curpos],y);
  curpos+=4;
  putSint32(&entityData2[curpos],z);
  curpos+=4;
  entityData2[curpos]=0; //Rotation
  entityData2[curpos+1]=0; //Pitch
  curpos+=2;
  putSint16(&entityData2[curpos],0); //current item
  curpos+=2;
  this->sendOthers((uint8 *)&entityData2[0], curpos);
  return true;
}
 
bool User::spawnOthers()
{
 
  for(unsigned int i=0;i<Users.size(); i++)
  {
    if(Users[i]->UID!=this->UID && Users[i]->nick != this->nick)
    {
      uint8 entityData2[256];
      int curpos=0;
      entityData2[curpos]=0x14; //Named Entity Spawn
      curpos++;
      putSint32(&entityData2[curpos], Users[i]->UID);        
      curpos+=4;
      entityData2[curpos]=0;
      entityData2[curpos+1]=Users[i]->nick.size();
      curpos+=2;
  
      for(unsigned int j=0;j<Users[i]->nick.size();j++)
      {
        entityData2[curpos]=Users[i]->nick[j];
        curpos++;
      }
  
      putSint32(&entityData2[curpos],(int)(Users[i]->pos.x*32));
      curpos+=4;
      putSint32(&entityData2[curpos],(int)(Users[i]->pos.y*32));
      curpos+=4;
      putSint32(&entityData2[curpos],(int)(Users[i]->pos.z*32));
      curpos+=4;
      entityData2[curpos]=0; //Rotation
      entityData2[curpos+1]=0; //Pitch
      curpos+=2;
      putSint16(&entityData2[curpos],0); //current item
      curpos+=2;
      bufferevent_write(this->buf_ev,(uint8 *)&entityData2[0], curpos);
    }
  }
  return true;
}
 
User *addUser(int sock,uint32 EID)
{
  User *newuser = new User(sock,EID);
  Users.push_back(newuser);
 
  return newuser;
}
 
bool remUser(int sock)
{        
  for(int i=0;i<(int)Users.size();i++)
  {
    if(Users[i]->fd==sock)
    {
      if(Users[i]->nick.size())
      {
        Chat::get().sendMsg(Users[i], Users[i]->nick+" disconnected!", OTHERS);
      }
      delete Users[i];
      Users.erase(Users.begin()+i);
      return true;
    }
  }
  return false;
}
 
bool isUser(int sock)
{
  uint8 i;
  for(i=0;i<Users.size();i++)
  {
      if(Users[i]->fd==sock)
          return true;
  }
  return false;
}
 
//Generate random and unique entity ID
uint32 generateEID()
{
  static uint32 EID = 0;
  /*
  bool finished=false;
  srand ( time(NULL) );
          
  while(!finished)
  {
    finished=true;
    EID=rand()%0xffffff;
 
    for(uint8 i=0;i<Users.size();i++)
    {
      if(Users[i]->UID==EID)
      {
        finished=false;
      }
    }
    for(uint8 i=0;i<Map::get().items.size();i++)
    {
      if(Map::get().items[i].EID==EID)
      {
        finished=false;
      }
    }
  }
  */
  return ++EID;
}
 
//Not case-sensitive search
User *getUserByNick(std::string nick) 
{
  // Get coordinates
  for(unsigned int i=0;i<Users.size();i++)
  {
    if(strToLower(Users[i]->nick) == strToLower(nick))
    {
      return Users[i];
    }
  }
  return false;
}
взял готовый код игры, и хочу на нем учиться, но даже ничего не меняя не могу скомпилировать =(
0
 Аватар для AlexeyDevil
21 / 21 / 4
Регистрация: 06.11.2010
Сообщений: 57
07.11.2010, 17:25
А ты шутник!!! Во-первых, тебе не хватает #include<zlib.h>, его точно нет в стандартных, его походу отдельно писали, во-вторых ты используешь не объявленную переменную, в-третьих тебе надо поменять типы переменных с int на double в 4 местах, а в четвертых если хочешь научится начни с чего ни то попроще! На форуме выложено сотни интересных прог, начни с них!
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
07.11.2010, 17:25
Помогаю со студенческими работами здесь

Стек. Исправить ошибки или добавить функцию удаления элемента из стека
Здравствуйте, не могли бы Вы мне помочь исправить ошибки и добавить простенькую функцию. Ошибки: строка 29 - отсутствуют экземпляры...

Как исправить ошибки
Условие:Вывести на экран цифры от 0 до 9. .model small .data .stack .code START: mov ax, @data mov ds,ax l1 ...

как исправить ошибки?
Никак не могу исправить то,что иногда,когда ввожу точку,программа показывает почему-то сразу две области,плюс когда точка...

Как исправить ошибки?
дано начало кода: using System; using System.Collections.Generic; using System.Linq; using System.Text; using...

Как исправить ошибки?
Вот эти ошибки как исправить? #include &lt;stdio.h&gt; #include &lt;stdlib.h&gt; #include &lt;string.h&gt; #include...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
5
Ответ Создать тему
Новые блоги и статьи
SDL3 для Web (WebAssembly): Подключение Box2D v3, физика и отрисовка коллайдеров
8Observer8 12.02.2026
Содержание блога Box2D - это библиотека для 2D физики для анимаций и игр. С её помощью можно определять были ли коллизии между конкретными объектами и вызывать обработчики событий столкновения. . . .
SDL3 для Web (WebAssembly): Загрузка PNG с прозрачным фоном с помощью SDL_LoadPNG (без SDL3_image)
8Observer8 11.02.2026
Содержание блога Библиотека SDL3 содержит встроенные инструменты для базовой работы с изображениями - без использования библиотеки SDL3_image. Пошагово создадим проект для загрузки изображения. . .
SDL3 для Web (WebAssembly): Загрузка PNG с прозрачным фоном с помощью SDL3_image
8Observer8 10.02.2026
Содержание блога Библиотека SDL3_image содержит инструменты для расширенной работы с изображениями. Пошагово создадим проект для загрузки изображения формата PNG с альфа-каналом (с прозрачным. . .
Установка Qt-версии Lazarus IDE в Debian Trixie Xfce
volvo 10.02.2026
В общем, достали меня глюки IDE Лазаруса, собранной с использованием набора виджетов Gtk2 (конкретно: если набирать текст в редакторе и вызвать подсказку через Ctrl+Space, то после закрытия окошка. . .
SDL3 для Web (WebAssembly): Работа со звуком через SDL3_mixer
8Observer8 08.02.2026
Содержание блога Пошагово создадим проект для загрузки звукового файла и воспроизведения звука с помощью библиотеки SDL3_mixer. Звук будет воспроизводиться по клику мышки по холсту на Desktop и по. . .
SDL3 для Web (WebAssembly): Основы отладки веб-приложений на SDL3 по USB и Wi-Fi, запущенных в браузере мобильных устройств
8Observer8 07.02.2026
Содержание блога Браузер Chrome имеет средства для отладки мобильных веб-приложений по USB. В этой пошаговой инструкции ограничимся работой с консолью. Вывод в консоль - это часть процесса. . .
SDL3 для Web (WebAssembly): Обработчик клика мыши в браузере ПК и касания экрана в браузере на мобильном устройстве
8Observer8 02.02.2026
Содержание блога Для начала пошагово создадим рабочий пример для подготовки к экспериментам в браузере ПК и в браузере мобильного устройства. Потом напишем обработчик клика мыши и обработчик. . .
Философия технологии
iceja 01.02.2026
На мой взгляд у человека в технических проектах остается роль генерального директора. Все остальное нейронки делают уже лучше человека. Они не могут нести предпринимательские риски, не могут. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru