00001
00002
00003
00004
00005
00006
00007
00008
00009 #import "ServerReader.h"
00010 #import "PacketTypesDebug.h"
00011
00012
00013 @implementation ServerReader
00014
00015
00016 int NUMOFBITS = {
00017 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4,
00018 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
00019 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
00020 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
00021 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
00022 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
00023 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
00024 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
00025 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
00026 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
00027 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
00028 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
00029 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
00030 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
00031 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
00032 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8
00033 };
00034
00035 int VTSIZE = {
00036 4, 8, 8, 12, 12, 16, 20, 20, 24
00037 };
00038
00039 int VTISIZE = {
00040 4, 7, 9, 11, 13, 16, 18, 20, 22
00041 };
00042
00043 int PACKET_SIZES = {
00044 0,
00045 84,
00046 4,
00047 8,
00048 12,
00049 8,
00050 12,
00051 16,
00052 8,
00053 12,
00054 84,
00055 84,
00056 32,
00057 4,
00058 28,
00059 12,
00060 4,
00061 104,
00062 8,
00063 4,
00064 4,
00065 4,
00066 4,
00067 56,
00068 52,
00069 20,
00070 28,
00071 0,
00072 8,
00073 4,
00074 4,
00075 36,
00076 12,
00077 0,
00078 0,
00079 0,
00080 0,
00081 0,
00082 0,
00083 60,
00084 8,
00085 -1,
00086 -1,
00087 12,
00088 12,
00089 -1,
00090 8,
00091 -1,
00092 -1,
00093 20,
00094 -1,
00095 0,
00096 0,
00097 0,
00098 0,
00099 0,
00100 0,
00101 -1,
00102 -1,
00103 36,
00104 88,
00105 524
00106 };
00107
00108 PacketTypesDebug *pktConv;
00109 NSMutableData *leftOverPacket;
00110
00111 - (id) init {
00112 self = [super init];
00113 if (self != nil) {
00114
00115 pktConv = [[PacketTypesDebug alloc] init];
00116 [pktConv setDebugPackets:NO];
00117 leftOverPacket = nil;
00118
00119
00120
00121 motd_done = NO;
00122
00123 notificationCenter = [LLNotificationCenter defaultCenter];
00124
00125 }
00126 return self;
00127 }
00128
00129 - (id)initWithUniverse:(Universe*)newUniverse communication:(Communication*)comm {
00130 self = [self init];
00131 if (self != nil) {
00132 universe = newUniverse;
00133 [universe retain];
00134 communication = comm;
00135 }
00136 return self;
00137 }
00138
00139 - (void) close {
00140 NSLog(@"ServerReader.close this should have been overwritten");
00141 }
00142
00143 - (NSData *) doRead {
00144 NSLog(@"ServerReader.doRead this should have been overwritten");
00145 return nil;
00146 }
00147
00148 - (void) readFromServer {
00149
00150 NSData *dataReceived = [self doRead];
00151 if (dataReceived == nil) {
00152 return;
00153 }
00154
00155 int count = 0;
00156 char *buffer = nil;
00157
00158
00159 if (leftOverPacket != nil) {
00160
00161 [leftOverPacket appendData:dataReceived];
00162
00163 count = [leftOverPacket length];
00164 buffer = (char*)[leftOverPacket bytes];
00165
00166 } else {
00167 count = [dataReceived length];
00168 buffer = (char*)[dataReceived bytes];
00169 }
00170
00171
00172
00173
00174
00175
00176
00177 while(count > 0) {
00178
00179 int ptype = buffer & 0xFF;
00180 if(ptype < 1 || ptype > SP_BITMAP) {
00181
00182
00183 NSLog(@"ServerReader.readFromServer received message: %@ (%d), count: %d",
00184 [pktConv serverPacketString:buffer[0]], buffer[0], count);
00185 bool oldSetting = [pktConv debugPackets];
00186 [pktConv setDebugPackets:YES];
00187 [pktConv printPacketInBuffer:buffer size:count];
00188 [pktConv setDebugPackets:oldSetting];
00189
00190
00191 NSLog(@"ServerReader.readFromServer: Unknown packet type. Flushing packet buffer & input stream.");
00192 NSLog([NSString stringWithFormat:@"ServerReader.readFromServer: Last packet type: %d", ptype]);
00193
00194 count = 0;
00195 buffer = nil;
00196 [leftOverPacket release];
00197 return;
00198 }
00199
00200 int size = PACKET_SIZES;
00201
00202
00203
00204 [pktConv printPacketInBuffer:buffer size:size];
00205
00206
00207
00208 if (size == -1) {
00209 if(count < 4) {
00210 NSLog(@"ServerReader.readFromServer: variable buffer too small");
00211 return;
00212 }
00213
00214 switch(ptype) {
00215 case SP_S_MESSAGE:
00216 size = buffer & 0xFF;
00217 break;
00218 case SP_S_WARNING:
00219 if(buffer[1] == STEXTE_STRING ||
00220 buffer[1] == SHORT_WARNING) {
00221 size = buffer & 0xFF;
00222 }
00223 else {
00224 size = 4;
00225 }
00226 break;
00227 case SP_S_PLAYER:
00228 if((buffer[1] & 0x80) != 0) {
00229
00230 size = (buffer & 0x3F) * 4 + 4;
00231 }
00232 else if((buffer[1] & 0x40) != 0) {
00233
00234 if ([communication shortVersion] == SHORTVERSION) {
00235 size = (buffer & 0x3F) * 4 + 4 + (buffer[2] & 0xFF) * 4;
00236 }
00237 else {
00238 size = (buffer & 0x3F) * 4 + 4;
00239 }
00240 }
00241 else {
00242
00243 size = (buffer & 0xFF) * 4 + 12;
00244 }
00245 break;
00246 case SP_S_TORP:
00247 size = VTSIZE;
00248 break;
00249 case SP_S_TORP_INFO :
00250 size = VTISIZE + NUMOFBITS[buffer & 0xFF];
00251 break;
00252 case SP_S_PLANET:
00253 size = (buffer & 0xFF) * 6 + 2;
00254 break;
00255 case SP_S_PHASER:
00256 switch(buffer[1] & 0x0F) {
00257 case PHASER_FREE :
00258 case PHASER_HIT :
00259 case PHASER_MISS :
00260 size = 4;
00261 break;
00262 case PHASER_HIT2 :
00263 size = 8;
00264 break;
00265 default:
00266 size = 12;
00267 break;
00268 }
00269 break;
00270 case SP_S_KILLS :
00271 size = (buffer & 0xFF) * 2 + 2;
00272 break;
00273 default:
00274 NSLog([NSString stringWithFormat:@"ServerReader.readFromServer: Unknown variable buffer: %c", ptype]);
00275 return;
00276 }
00277
00278 if ((size % 4) != 0) {
00279 size += (4 - (size % 4));
00280 }
00281 if (size <= 0) {
00282 NSLog([NSString stringWithFormat:@"ServerReader.readFromServer: bad size: %d", size]);
00283 NSLog([NSString stringWithFormat:@"ServerReader.readFromServer: for packet type: %c", ptype]);
00284 return;
00285 }
00286 }
00287
00288
00289 if(count < size) {
00290
00291 [leftOverPacket release];
00292 leftOverPacket = [NSMutableData dataWithBytes:buffer length:count];
00293 [leftOverPacket retain];
00294 return;
00295 }
00296
00297
00298
00299 [[universe synchronizeAccess] lock];
00300
00301 [[universe synchronizeAccess] unlock];
00302 bool result = [self handlePacket:ptype withSize:size inBuffer:buffer];
00303
00304
00305 if (result) {
00306
00307 count -= size;
00308
00309
00310 buffer += size;
00311 } else {
00312 NSLog(@"ServerReader.readFromServer packet %d was not handled correctly", buffer[0]);
00313 }
00314
00315
00316 [leftOverPacket release];
00317 leftOverPacket = nil;
00318
00319 }
00320 }
00321
00322
00323
00324
00325
00326
00328 int intFromPacket(char *buffer, int offset) {
00329 return (buffer[offset] & 0xFF) << 24 | (buffer & 0xFF) << 16
00330 | (buffer[offset + 2] & 0xFF) << 8 | buffer & 0xFF;
00331 }
00332
00334 int shortFromPacket(char *buffer, int offset) {
00335 return (buffer[offset] & 0xFF) << 8 | buffer & 0xFF;
00336 }
00337
00339 -(void) newFlags:(int)dat target:(int)which {
00340 int status;
00341 int new_flags_set;
00342 Player *player;
00343 for(int pnum = which * 16; pnum < (which + 1) * 16 && pnum < [universe playerCount]; ++pnum) {
00344
00345 new_flags_set = dat & 0x03;
00346 dat >>= 2;
00347
00348 player = [universe playerWithId: pnum];
00349 if([player status] == PLAYER_FREE) {
00350 continue;
00351 }
00352
00353 switch(new_flags_set) {
00354 case 0 :
00355 status = PLAYER_EXPLODE;
00356 [player setFlags: [player flags] & ~PLAYER_CLOAK];
00357 break;
00358 case 1 :
00359 status = PLAYER_ALIVE;
00360 [player setFlags: [player flags] | PLAYER_CLOAK];
00361 break;
00362 case 2 :
00363 status = PLAYER_ALIVE;
00364 [player setFlags: [player flags] | PLAYER_SHIELD];
00365 [player setFlags: [player flags] & ~PLAYER_CLOAK];
00366 break;
00367 case 3 :
00368 status = PLAYER_ALIVE;
00369 [player setFlags: [player flags] & ~(PLAYER_SHIELD | PLAYER_CLOAK)];
00370 break;
00371 default:
00372 status = 0;
00373 break;
00374 }
00375
00376 if ([player status] == status) {
00377 continue;
00378 }
00379
00380 if (status == PLAYER_EXPLODE) {
00381 if ([player status] == PLAYER_ALIVE) {
00382 [player setExplode: 0];
00383 [player setStatus: status];
00384 }
00385 }
00386 else {
00387 if([player isMe]) {
00388
00389
00390
00391
00392 if ([player status] == PLAYER_OUTFIT || [player status] == PLAYER_FREE) {
00393 [player setStatus: PLAYER_ALIVE];
00394 }
00395 }
00396 else {
00397 [player setStatus: status];
00398 }
00399 }
00400 }
00401 }
00402
00403
00404
00405 -(void) handleUdpReply:(char*) buffer {
00406
00407 NSLog([NSString stringWithFormat:@"ServerReader.handleUdpReply: UDP: Received UDP reply %c", (buffer[1])]);
00408
00409 switch (buffer[1] & 0xFF) {
00410 case SWITCH_TCP_OK:
00411 if ([communication commMode] == COMM_TCP) {
00412 NSLog(@"ServerReader.handleUdpReply: Got SWITCH_TCP_OK while in TCP mode; ignoring");
00413 }
00414 else {
00415 [communication setCommMode: COMM_TCP];
00416 [communication setCommStatus: STAT_CONNECTED];
00417 NSLog(@"ServerReader.handleUdpReply: Connected to server's TCP port");
00418
00419 [notificationCenter postNotificationName:@"SP_UDP_SWITCHED_TO_TCP" object:self userInfo:nil];
00420 }
00421 break;
00422 case SWITCH_UDP_OK:
00423 if ([communication commMode] == COMM_UDP) {
00424 NSLog(@"ServerReader.handleUdpReply: Got SWITCH_UDP_OK while in UDP mode; ignoring");
00425 }
00426 else {
00427
00428 if ([communication commModeRequest] != COMM_UDP) {
00429 NSLog(@"ServerReader.handleUdpReply: Got unsolicited SWITCH_UDP_OK; ignoring");
00430 }
00431 else {
00432 NSLog(@"ServerReader.handleUdpReply: Connected to server's UDP port");
00433 [communication setCommMode: COMM_UDP];
00434 [communication setCommStatus: STAT_VERIFY_UDP];
00435 int port = intFromPacket(buffer, 4);
00436
00437
00438 [communication connectToServerUsingPort:port];
00439
00440 [notificationCenter postNotificationName:@"SP_TCP_SWITCHED_TO_UDP"
00441 object:self
00442 userInfo:[NSNumber numberWithInt:port]];
00443 }
00444 }
00445 break;
00446 case SWITCH_DENIED:
00447
00448 if (intFromPacket(buffer, 4) == 0) {
00449 NSLog(@"ServerReader.handleUdpReply: Switch to UDP failed (different version)");
00450 }
00451 else {
00452 NSLog(@"ServerReader.handleUdpReply: Switch to UDP denied");
00453 }
00454
00455 [communication setCommModeRequest:[communication commMode]];
00456 [communication setCommStatus: STAT_CONNECTED];
00457
00458
00459
00460 [notificationCenter postNotificationName:@"SP_SWITCHED_DENIED" object:self userInfo:nil];
00461 break;
00462 case SWITCH_VERIFY:
00463 [notificationCenter postNotificationName:@"SP_SWITCH_VERIFY" object:self userInfo:nil];
00464 NSLog(@"ServerReader.handleUdpReply: Received UDP verification");
00465
00466
00467 [notificationCenter postNotificationName:@"SP_ASK_FOR_COMM_UPDATE" object:self userInfo:nil];
00468 break;
00469 default:
00470 NSLog([NSString stringWithFormat: @"ServerReader.handleUdpReply: Got funny reply (%c) in UDP_REPLY packet",
00471 (buffer[1])]);
00472 break;
00473 }
00474 }
00475
00476
00477
00478
00479 -(void) handleVPlayer:(char *)buffer {
00480 int x, y, player_index, save;
00481 Player *player;
00482 int numofplayers = buffer & 0x3F;
00483
00484 int pos = 0;
00485
00486
00487
00488
00489
00490 if ((buffer[1] & 0x40) != 0) {
00491 if ([communication shortVersion] == SHORTVERSION) {
00492 if (buffer[2] == 2) {
00493 [self newFlags: intFromPacket(buffer, 4) target:buffer & 0xFF];
00494 [self newFlags: intFromPacket(buffer, 8) target: 0];
00495 pos += 8;
00496 }
00497 else if (buffer[2] == 1) {
00498 [self newFlags: intFromPacket(buffer, 4) target: buffer & 0xFF];
00499 pos += 4;
00500 }
00501 }
00502 pos += 4;
00503 for(int p = 0; p < numofplayers; p++) {
00504 player_index = buffer & 0x1F;
00505 if(player_index >= [universe playerCount]) {
00506 continue;
00507 }
00508 save = buffer;
00509 pos++;
00510 player = [universe playerWithId:player_index];
00511
00512
00513 [player setSpeed: (buffer & 0x0F)];
00514
00515 FeatureList *fList = [communication featureList];
00516 if([player isMe] && [fList valueForFeature: FEATURE_LIST_CLOAK_MAXWARP] != FEATURE_OFF) {
00517 if([player speed] == 0xF) {
00518 [player setFlags: [player flags] | PLAYER_CLOAK];
00519 }
00520 else if(([player flags] & PLAYER_CLOAK) != 0) {
00521 [player setFlags: [player flags] & ~PLAYER_CLOAK];
00522 }
00523 }
00524
00525
00526 [player setNetrekFormatCourse: ((buffer & 0xFF) >> 4) * 16];
00527 pos++;
00528 x = buffer & 0xFF;
00529 pos++;
00530 y = buffer & 0xFF;
00531 pos++;
00532
00533
00534
00535 NSPoint position;
00536 if((save & 0x40) != 0) {
00537 x |= 0x100;
00538 }
00539 if((save & 0x80) != 0) {
00540 y |= 0x100;
00541 }
00542
00543 if((save & 0x20) != 0) {
00544
00545 if (x == 501 || y == 501) {
00546 x = -500;
00547 y = -500;
00548 }
00549
00550
00551 position.x = x * (UNIVERSE_PIXEL_SIZE / SPWINSIDE);
00552 position.y = y * (UNIVERSE_PIXEL_SIZE / SPWINSIDE);
00553 }
00554 else {
00555
00556
00557 Player *me = [universe playerThatIsMe];
00558 NSPoint myPos = [me position];
00559 position.x = myPos.x + ((x - SPWINSIDE / 2) * UNIVERSE_SCALE);
00560 position.y = myPos.y + ((y - SPWINSIDE / 2) * UNIVERSE_SCALE);
00561 }
00562 [player setPosition:position];
00563
00564
00565
00566
00567
00568
00569
00570
00571
00572
00573
00574
00575
00576 [notificationCenter postNotificationName:@"SP_V_PLAYER" object:self userInfo:player];
00577 }
00578 }
00579 else {
00580
00581 player = [universe playerThatIsMe];
00582 [player setNetrekFormatCourse:buffer & 0xFF];
00583 [player setSpeed: buffer & 0xFF];
00584
00585
00586 FeatureList *fList = [communication featureList];
00587 if([fList valueForFeature: FEATURE_LIST_CLOAK_MAXWARP] != FEATURE_OFF) {
00588 if([player speed] == 0xF) {
00589 [player setFlags: [player flags] | PLAYER_CLOAK];
00590 }
00591 else if(([player flags] & PLAYER_CLOAK) != 0) {
00592 [player setFlags: [player flags] & ~PLAYER_CLOAK];
00593 }
00594 }
00595
00596 NSPoint position;
00597 if ([communication shortVersion] == SHORTVERSION) {
00598 position.x = UNIVERSE_SCALE * shortFromPacket(buffer, 4);
00599 position.y = UNIVERSE_SCALE * shortFromPacket(buffer, 6);
00600 [self newFlags: intFromPacket(buffer, 8) target: 0];
00601 }
00602 else {
00603 position.x = intFromPacket(buffer, 4);
00604 position.y = intFromPacket(buffer, 8);
00605 }
00606 [player setPosition:position];
00607
00608
00609
00610
00611
00612
00613
00614
00615
00616
00617
00618
00619
00620
00621
00622 if (buffer[1] == 0) {
00623 return;
00624 }
00625 pos += 12;
00626
00627
00628 for(int p = 0; p < [universe playerCount]; ++p) {
00629 player_index = buffer & 0x1F;
00630 if (player_index >= [universe playerCount]) {
00631 continue;
00632 }
00633 save = buffer;
00634 pos++;
00635 player = [universe playerWithId:player_index];
00636
00637
00638 [player setSpeed: buffer & 0xFF];
00639
00640
00641 FeatureList *fList = [communication featureList];
00642 if([player isMe] && [fList valueForFeature: FEATURE_LIST_CLOAK_MAXWARP] != FEATURE_OFF) {
00643 if([player speed] == 0xF) {
00644 [player setFlags: [player flags] | PLAYER_CLOAK];
00645 }
00646 else if(([player flags] & PLAYER_CLOAK) != 0) {
00647 [player setFlags: [player flags] & ~PLAYER_CLOAK];
00648 }
00649 }
00650
00651
00652 [player setNetrekFormatCourse: ((buffer & 0xFF) >> 4) * 16];
00653 pos++;
00654 x = buffer & 0xFF;
00655 pos++;
00656 y = buffer & 0xFF;
00657 pos++;
00658
00659
00660
00661 NSPoint position;
00662 if((save & 0x40) != 0) {
00663 x |= 0x100;
00664 }
00665 if((save & 0x80) != 0) {
00666 y |= 0x100;
00667 }
00668
00669 if((save & 0x20) != 0) {
00670
00671 if (x == 501 || y == 501) {
00672 x = -500;
00673 y = -500;
00674 }
00675
00676
00677 position.x = x * (UNIVERSE_PIXEL_SIZE / SPWINSIDE);
00678 position.y = y * (UNIVERSE_PIXEL_SIZE / SPWINSIDE);
00679 }
00680 else {
00681
00682
00683 Player *me = [universe playerThatIsMe];
00684 NSPoint myPos = [me position];
00685 position.x = myPos.x + ((x - SPWINSIDE / 2) * UNIVERSE_SCALE);
00686 position.y = myPos.y + ((y - SPWINSIDE / 2) * UNIVERSE_SCALE);
00687 }
00688 [player setPosition:position];
00689
00690
00691
00692
00693
00694
00695
00696
00697
00698
00699
00700
00701
00702 [notificationCenter postNotificationName:@"SP_V_PLAYER" object:self userInfo:player];
00703 }
00704 }
00705 }
00706
00708 -(void) handleVTorp:(char*)buffer {
00709
00710 int torp_index = 0;
00711 int bitset;
00712 int dx;
00713 int dy;
00714 int shiftvar;
00715 int torp_data_pos;
00716
00717 if(buffer[0] == SP_S_8_TORP) {
00718 bitset = 0xFF;
00719 torp_index = (buffer & 0xFF) * 8;
00720 torp_data_pos = 2;
00721 }
00722 else {
00723 bitset = buffer;
00724 torp_index = (buffer & 0xFF) * 8;
00725 torp_data_pos = 3;
00726 }
00727
00728 int shift = 0;
00729 Torp *torp;
00730
00731 for(int t = 0; t < 8; ++t, ++torp_index, bitset >>= 1) {
00732 torp = [universe torpWithId:torp_index];
00733
00734 if((bitset & 0x01) != 0) {
00735
00736 dx = ((buffer[torp_data_pos] & 0xFF) >> shift);
00737 shiftvar = (buffer & 0xFF) << (8 - shift);
00738 dx |= (shiftvar & 0x1FF);
00739 shift++;
00740
00741
00742 dy = ((buffer & 0xFF) >> shift);
00743 shiftvar = (buffer & 0xFF) << (8 - shift);
00744 dy |= (shiftvar & 0x1FF);
00745 shift++;
00746
00747 if (shift == 8) {
00748 shift = 0;
00749 ++torp_data_pos;
00750 }
00751
00752
00753 if ([torp status] == TORP_FREE) {
00754
00755 [torp setStatus: TORP_MOVE];
00756 }
00757 else if ([[torp owner] isMe] && [torp status] == TORP_EXPLODE) {
00758 [torp setStatus: TORP_MOVE];
00759 }
00760
00761 NSPoint pos;
00762
00763 if (dx > SPWINSIDE || dy > SPWINSIDE) {
00764 pos.x = -100000;
00765 pos.y = -100000;
00766 }
00767 else {
00768
00769
00770
00771
00772
00773
00774
00775
00776
00777
00778
00779
00780 pos.x = dx;
00781 pos.y = dy;
00782 }
00783 }
00784 else {
00785 if([torp status] != TORP_FREE && [torp status] != TORP_EXPLODE) {
00786 [torp setStatus: TORP_FREE];
00787 }
00788 }
00789 [notificationCenter postNotificationName:@"SP_V_TORP" object:self userInfo:torp];
00790 }
00791
00792 }
00793
00795 - (void) handleVTorpInfo:(char*) buffer {
00796 int torp_index = 0;
00797
00798 int dx;
00799 int dy;
00800 int shiftvar;
00801 int status;
00802 char war;
00803
00804 int bitset = buffer & 0xFF;
00805 torp_index = (buffer & 0xFF) * 8;
00806 int infobitset = buffer & 0xFF;
00807
00808 int torp_data_pos = 4;
00809 int info_data_pos = VTISIZE;
00810
00811 int shift = 0;
00812
00813 Torp *torp;
00814
00815 for(int t = 0; t < 8; ++t, ++torp_index, bitset >>= 1, infobitset >>= 1) {
00816 torp = [universe torpWithId:torp_index];
00817
00818 if((bitset & 0x01) != 0) {
00819
00820 dx = ((buffer[torp_data_pos] & 0xFF) >> shift);
00821 shiftvar = (buffer & 0xFF) << (8 - shift);
00822 dx |= (shiftvar & 0x1FF);
00823 shift++;
00824
00825
00826 dy = ((buffer & 0xFF) >> shift);
00827 shiftvar = (buffer & 0xFF) << (8 - shift);
00828 dy |= (shiftvar & 0x1FF);
00829 shift++;
00830
00831 if (shift == 8) {
00832 shift = 0;
00833 ++torp_data_pos;
00834 }
00835
00836
00837 if ((infobitset & 0x01) == 0) {
00838 if([torp status] == TORP_FREE) {
00839
00840 [torp setStatus: TORP_MOVE];
00841 } else if ([[torp owner] isMe] && [torp status] == TORP_EXPLODE) {
00842 [torp setStatus: TORP_MOVE];
00843 }
00844 }
00845 NSPoint pos;
00846
00847 if (dx > SPWINSIDE || dy > SPWINSIDE) {
00848 pos.x = -100000;
00849 pos.y = -100000;
00850 }
00851 else {
00852
00853
00854
00855
00856
00857
00858
00859
00860
00861
00862
00863
00864 pos.x = dx;
00865 pos.y = dy;
00866 }
00867 }
00868 else {
00869 if ((infobitset & 0x01) == 0) {
00870
00871 if([torp status] != TORP_FREE && [torp status] != TORP_EXPLODE) {
00872 [torp setStatus: TORP_FREE];
00873 }
00874 }
00875 }
00876
00877 if((infobitset & 0x01) != 0) {
00878 war = (char)(buffer[info_data_pos] & 0xF0);
00879 status = (buffer & 0xF0) >> 4;
00880 info_data_pos++;
00881
00882 if (status == TORP_EXPLODE && [torp status] == TORP_FREE) {
00883
00884 continue;
00885 }
00886 [torp setWar:war];
00887 if(status != [torp status]) {
00888
00889 [torp setStatus: status];
00890 }
00891 }
00892 [notificationCenter postNotificationName:@"SP_V_TORP_INFO" object:self userInfo:torp];
00893 }
00894 }
00895
00896 -(void) handleVPlanet:(char*)buffer {
00897 int planet_index = 0;
00898 bool redraw = NO;
00899 int numofplanets = buffer & 0xFF;
00900 int ownerId;
00901 int info;
00902 int flags;
00903 int armies;
00904 Team *owner;
00905
00906 Planet *planet;
00907 for(int pos = 2, p = 0; p < numofplanets; ++p, pos += 2) {
00908 planet_index = buffer & 0xFF;
00909 planet = [universe planetWithId: planet_index];
00910 redraw = NO;
00911
00912 @try {
00913
00914 ownerId = buffer & 0xFF;
00915 owner = [universe teamWithId:[universe remappedTeamIdWithId: ownerId]];
00916 if ([planet owner] != owner) {
00917 redraw = YES;
00918 [universe movePlanet:planet toTeam:owner];
00919 [owner addPlanet:planet];
00920 }
00921 }
00922 @catch (NSException * e) {
00923 NSLog([NSString stringWithFormat: @"ServerReader.handleVPlanet: planet owner out of bounds: ", ownerId]);
00924 NSLog([NSString stringWithFormat: @"ServerReader.handleVPlanet: planet : ", planet_index]);
00925 [universe movePlanet:planet toTeam:[universe teamWithId:TEAM_NOBODY]];
00926 }
00927
00928
00929 info = buffer & 0xFF;
00930 if ([planet info] != info) {
00931 [planet setInfo: info];
00932 if([planet info] == 0) {
00933 [universe movePlanet:planet toTeam:[universe teamWithId:TEAM_NOBODY]];
00934 }
00935 redraw = YES;
00936 }
00937
00938
00939 armies = buffer & 0xFF;
00940 if ([planet armies] != armies
00941
00942
00943 && (([planet armies] < 5 && armies > 4) || ([planet armies] > 4 && armies < 5))) {
00944 redraw = YES;
00945 }
00946 [planet setArmies: armies];
00947
00948
00949 flags = shortFromPacket(buffer, ++pos);
00950 if ([planet flags] != flags) {
00951 [planet setFlags: flags];
00952 redraw = YES;
00953 }
00954
00955 if (redraw) {
00956 [planet setFlags: ([planet flags] | PLANET_REDRAW)];
00957 }
00958 [notificationCenter postNotificationName:@"SP_V_PLANET" object:self userInfo:planet];
00959 }
00960
00961 }
00962
00963 -(void) handleVPhaser:(char *)buffer {
00964
00965 int pnum = buffer & 0x3F;
00966 int x = 0;
00967 int y = 0;
00968 int dir = 0;
00969 int target = 0;
00970
00971 int status = buffer & 0x0F;
00972
00973 Phaser *phaser = [universe phaserWithId:pnum];
00974 [phaser setStatus: status];
00975
00976 switch(status) {
00977 case PHASER_FREE:
00978 break;
00979 case PHASER_HIT:
00980 target = buffer & 0x3F;
00981 break;
00982 case PHASER_MISS:
00983 dir = buffer & 0xFF;
00984 break;
00985 case PHASER_HIT2:
00986 x = UNIVERSE_SCALE * shortFromPacket(buffer, 4);
00987 y = UNIVERSE_SCALE * shortFromPacket(buffer, 6);
00988 target = buffer & 0x3F;
00989 break;
00990 default:
00991 x = UNIVERSE_SCALE * shortFromPacket(buffer, 4);
00992 y = UNIVERSE_SCALE * shortFromPacket(buffer, 6);
00993 target = buffer & 0x3F;
00994 dir = buffer & 0xFF;
00995 break;
00996 }
00997
00998 NSPoint pos;
00999 pos.x = x;
01000 pos.y = y;
01001 [phaser setPosition:pos];
01002 [phaser setNetrekFormatCourse:dir];
01003
01004 if (status != PHASER_FREE) {
01005
01006 Ship *ship = [universe shipWithPhaserId:pnum];
01007 [phaser setMaxFuse:[ship maxPhaserFuse]];
01008 }
01009
01010 [phaser setTarget:[universe playerWithId:target]];
01011 [phaser setFuse:0];
01012
01013 [notificationCenter postNotificationName:@"SP_V_PHASER" object:self userInfo:phaser];
01014
01015
01016
01017
01018
01019
01020
01021
01022
01023
01024
01025 }
01026
01027 - (void) handleSequence:(char *) buffer {
01028 NSLog(@"ServerReader.handleSequence: SP_SEQUENCE not implemented");
01029 }
01030
01032 - (bool) handlePacket:(int)ptype withSize:(int)size inBuffer:(char *)buffer {
01033
01034
01035
01036
01037
01038
01039 switch(ptype) {
01040 case SP_MESSAGE :
01041 @try {
01042 NSString *message = [self stringFromBuffer:buffer startFrom:4 maxLength:80];
01043 NSNumber *flags = [NSNumber numberWithInt: buffer & 0xFF];
01044 NSNumber *from = [NSNumber numberWithInt: buffer & 0xFF];
01045 NSNumber *to = [NSNumber numberWithInt: buffer & 0xFF];
01046 NSDictionary *obj = [NSDictionary dictionaryWithObjectsAndKeys:
01047 message, @"message", flags, @"flags", from, @"from", to, @"to", nil];
01048 [notificationCenter postNotificationName:@"SP_MESSAGE" object:self userInfo:obj];
01049 }
01050 @catch (NSException * e) {
01051 NSLog(@"ServerReader.handlePacket: SP_MESSAGE error");
01052 NSLog([NSString stringWithFormat:@"%@: %@", [e name], [e reason]]);
01053 }
01054 break;
01055 case SP_PLAYER_INFO :
01056 @try {
01057 int playerId = buffer;
01058 Player *player = [universe playerWithId:playerId];
01059 int shipType = buffer;
01060 Ship *ship = [universe shipOfType:shipType];
01061 [player setShip:ship];
01062 int teamId = [universe remappedTeamIdWithId: buffer];
01063 if (teamId > TEAM_MAX) {
01064 NSLog(@"ServerReader.handlePacket: SP_PLAYER_INFO error team %d unknown", teamId);
01065 break;
01066 }
01067 Team *team = [universe teamWithId:teamId];
01068 [player setTeam:team];
01069 [universe movePlayer:player toTeam:team];
01070 [notificationCenter postNotificationName:@"SP_PLAYER_INFO" object:self userInfo:player];
01071 }
01072 @catch (NSException * e) {
01073 NSLog(@"ServerReader.handlePacket: SP_PLAYER_INFO error");
01074 NSLog([NSString stringWithFormat:@"%@: %@", [e name], [e reason]]);
01075 }
01076 break;
01077 case SP_KILLS :
01078 @try {
01079 int playerId = buffer;
01080 Player *player = [universe playerWithId:playerId];
01081 [player setKills: ((float)intFromPacket(buffer, 4) / 100)];
01082
01083 }
01084 @catch (NSException * e) {
01085 NSLog(@"ServerReader.handlePacket: SP_KILLS error");
01086 NSLog([NSString stringWithFormat:@"%@: %@", [e name], [e reason]]);
01087 }
01088 break;
01089 case SP_PLAYER :
01090 @try {
01091 int playerId = buffer;
01092 Player *player = [universe playerWithId:playerId];
01093
01094 NSPoint pos;
01095 pos.x = intFromPacket(buffer, 4);
01096 pos.y = intFromPacket(buffer, 8);
01097
01098
01099
01100
01101
01102
01103
01104
01105
01106
01107 [player setNetrekFormatCourse: (buffer & 0xFF)];
01108 [player setPosition:pos];
01109 [player setSpeed: (buffer & 0xFF)];
01110
01111 }
01112 @catch (NSException * e) {
01113 NSLog(@"ServerReader.handlePacket: SP_PLAYER error");
01114 NSLog([NSString stringWithFormat:@"%@: %@", [e name], [e reason]]);
01115 }
01116 break;
01117 case SP_TORP_INFO :
01118 @try {
01119 Torp *torp = [universe torpWithId:shortFromPacket(buffer, 4)];
01120 int status = buffer;
01121 if(status != [torp status]) {
01122 if(status == TORP_EXPLODE && [torp status] == TORP_FREE) {
01123 return YES;
01124 }
01125
01126 [torp setStatus: status];
01127 }
01128 int war = buffer;
01129 [torp setWar: war];
01130
01131 }
01132 @catch (NSException * e) {
01133 NSLog(@"ServerReader.handlePacket: SP_TORP_INFO error");
01134 NSLog([NSString stringWithFormat:@"%@: %@", [e name], [e reason]]);
01135 }
01136 break;
01137 case SP_TORP :
01138 @try {
01139 Torp *torp = [universe torpWithId:shortFromPacket(buffer, 2)];
01140
01141 NSPoint pos;
01142 pos.x = intFromPacket(buffer, 4);
01143 pos.y = intFromPacket(buffer, 8);
01144
01145
01146
01147
01148
01149
01150 [torp setNetrekFormatCourse: (buffer & 0xFF)];
01151 [torp setPosition: pos];
01152
01153 }
01154 @catch (NSException * e) {
01155 NSLog(@"ServerReader.handlePacket: SP_TORP error");
01156 NSLog([NSString stringWithFormat:@"%@: %@", [e name], [e reason]]);
01157 }
01158 break;
01159 case SP_PHASER :
01160 @try {
01161
01162 int phaserId = buffer;
01163 Phaser *phaser = [universe phaserWithId:phaserId];
01164
01165 int playerId = intFromPacket(buffer, 12);
01166 Player *target = [universe playerWithId:playerId];
01167
01168 [phaser setTarget: target];
01169 int status = buffer;
01170 [phaser setStatus: status];
01171
01172 if(status != PHASER_FREE) {
01173
01174 Ship *ship = [universe shipWithPhaserId:phaserId];
01175 [phaser setMaxFuse:[ship maxPhaserFuse]];
01176 }
01177
01178
01179
01180
01181
01182
01183
01184
01185 NSPoint pos;
01186 pos.x = intFromPacket(buffer, 4);
01187 pos.y = intFromPacket(buffer, 8);
01188 [phaser setPosition: pos];
01189
01190 [phaser setNetrekFormatCourse: (buffer & 0xFF)];
01191
01192 [phaser setFuse: 0];
01193
01194
01195 }
01196 @catch (NSException * e) {
01197 NSLog(@"ServerReader.handlePacket: SP_PHASER error");
01198 NSLog([NSString stringWithFormat:@"%@: %@", [e name], [e reason]]);
01199 }
01200 break;
01201 case SP_PLASMA_INFO :
01202 @try {
01203 Plasma *plasma = [universe plasmaWithId:shortFromPacket(buffer, 4)];
01204 int status = buffer;
01205 if(status != [plasma status]) {
01206 if(status == PLASMA_EXPLODE && [plasma status] == PLASMA_FREE) {
01207 return YES;
01208 }
01209 [plasma setStatus: status];
01210 }
01211 int war = buffer;
01212 [plasma setWar: war];
01213
01214 }
01215 @catch (NSException * e) {
01216 NSLog(@"ServerReader.handlePacket: SP_PLASMA_INFO error");
01217 NSLog([NSString stringWithFormat:@"%@: %@", [e name], [e reason]]);
01218 }
01219 break;
01220 case SP_PLASMA :
01221 @try {
01222
01223 Plasma *plasma = [universe plasmaWithId:shortFromPacket(buffer, 2)];
01224
01225 NSPoint pos;
01226 pos.x = intFromPacket(buffer, 4);
01227 pos.y = intFromPacket(buffer, 8);
01228
01229
01230
01231
01232
01233
01234 [plasma setNetrekFormatCourse: (buffer & 0xFF)];
01235 [plasma setPosition: pos];
01236
01237 }
01238 @catch (NSException * e) {
01239 NSLog(@"ServerReader.handlePacket: SP_PLASMA error");
01240 NSLog([NSString stringWithFormat:@"%@: %@", [e name], [e reason]]);
01241 }
01242 break;
01243 case SP_WARNING :
01244 @try {
01245 NSString *warning = [self stringFromBuffer:buffer startFrom:4 maxLength:80];
01246 [notificationCenter postNotificationName:@"SP_WARNING" object:self userInfo:warning];
01247 }
01248 @catch (NSException * e) {
01249 NSLog(@"ServerReader.handlePacket: SP_WARNING error");
01250 NSLog([NSString stringWithFormat:@"%@: %@", [e name], [e reason]]);
01251 }
01252 break;
01253 case SP_MOTD :
01254 @try {
01255 NSString *line = [self stringFromBuffer:buffer startFrom:4 maxLength:80];
01256 if([line hasPrefix:@"\t@@@"]) {
01257 motd_done = YES;
01258 }
01259 else if(!motd_done) {
01260
01261
01262 }
01263 else {
01264
01265
01266 }
01267 }
01268 @catch (NSException * e) {
01269 NSLog(@"ServerReader.handlePacket: SP_MOTD error");
01270 NSLog([NSString stringWithFormat:@"%@: %@", [e name], [e reason]]);
01271 }
01272 break;
01273 case SP_YOU :
01274 @try {
01275 int ghostSlot = ([communication ghostSlot] == -1) ? buffer[1] : [communication ghostSlot];
01276 Player *me;
01277 if (ghostSlot == -1) {
01278 int playerId = buffer;
01279 me = [universe playerWithId:playerId];
01280 } else {
01281 me = [universe playerWithId:ghostSlot];
01282 }
01283
01284 [me updateHostile: buffer
01285 stickyWar: buffer
01286 armies: buffer
01287 flags: intFromPacket(buffer, 8)
01288 damage: intFromPacket(buffer, 12)
01289 shieldStrenght: intFromPacket(buffer, 16)
01290 fuel: intFromPacket(buffer, 20)
01291 engineTemp: (short)shortFromPacket(buffer, 24)
01292 weaponsTemp: (short)shortFromPacket(buffer, 26)
01293 whyDead: (short)shortFromPacket(buffer, 28)
01294 whoKilledMe: (short)shortFromPacket(buffer, 30)
01295 thisIsMe: YES];
01296
01297 if(([me flags] & PLAYER_PLOCK) != 0) {
01298 if (([me flags] & PLAYER_OBSERV) != 0) {
01299 [[universe status] setObserver:YES];
01300 }
01301 else {
01302 [[universe status] setObserver:NO];
01303 }
01304 }
01305 else {
01306 [[universe status] setObserver:NO];
01307 }
01308
01309 }
01310 @catch (NSException * e) {
01311 NSLog(@"ServerReader.handlePacket: SP_YOU error");
01312 NSLog([NSString stringWithFormat:@"%@: %@", [e name], [e reason]]);
01313 }
01314 break;
01315 case SP_QUEUE :
01316 @try {
01317 NSNumber *queueSize = [NSNumber numberWithInt:(int)shortFromPacket(buffer, 2)];
01318 [notificationCenter postNotificationName:@"SP_QUEUE" object:self userInfo:queueSize];
01319 }
01320 @catch (NSException * e) {
01321 NSLog(@"ServerReader.handlePacket: SP_QUEUE error");
01322 NSLog([NSString stringWithFormat:@"%@: %@", [e name], [e reason]]);
01323 }
01324 break;
01325 case SP_STATUS :
01326 @try {
01327 Status *status = [universe status];
01328
01329 [status updateTournament: (buffer != 0)
01330 armiesBombed: intFromPacket(buffer, 4)
01331 planetsTaken: intFromPacket(buffer, 8)
01332 kills: intFromPacket(buffer, 12)
01333 losses: intFromPacket(buffer, 16)
01334 time: intFromPacket(buffer, 20)
01335 timeProd: intFromPacket(buffer, 24)];
01336
01337 }
01338 @catch (NSException * e) {
01339 NSLog(@"ServerReader.handlePacket: SP_STATUS error");
01340 NSLog([NSString stringWithFormat:@"%@: %@", [e name], [e reason]]);
01341 }
01342 break;
01343 case SP_PLANET :
01344 @try {
01345 Planet *planet = [universe planetWithId:(buffer)];
01346
01347
01348 [planet setInfo: (buffer)];
01349 [planet setFlags: shortFromPacket(buffer, 4)];
01350 [planet setArmies: intFromPacket(buffer, 8)];
01351 [planet setNeedsDisplay: YES];
01352
01353
01354 int teamId = [universe remappedTeamIdWithId: buffer];
01355 Team *team = [universe teamWithId:teamId];
01356 [universe movePlanet:planet toTeam:team];
01357 [team addPlanet:planet];
01358
01359
01360 }
01361 @catch (NSException * e) {
01362 NSLog(@"ServerReader.handlePacket: SP_PLANET error");
01363 NSLog([NSString stringWithFormat:@"%@: %@", [e name], [e reason]]);
01364 }
01365 break;
01366 case SP_PICKOK :
01367 @try
01368 {
01369 bool pickOk = (buffer != 0);
01370 if (pickOk) {
01371 [notificationCenter postNotificationName:@"SP_PICKOK" object:self userInfo:nil];
01372 } else {
01373 [notificationCenter postNotificationName:@"SP_PICKNOK" object:self userInfo:nil];
01374 }
01375 }
01376 @catch (NSException * e) {
01377 NSLog(@"ServerReader.handlePacket: SP_PICKOK error");
01378 NSLog([NSString stringWithFormat:@"%@: %@", [e name], [e reason]]);
01379 }
01380 break;
01381 case SP_LOGIN :
01382 @try {
01383
01384 if(buffer[2] == 69 && buffer[3] == 42) {
01385 [notificationCenter postNotificationName:@"SP_LOGIN_INVALID_SERVER" object:self userInfo:nil];
01386 return NO;
01387 }
01388 Player *me = [universe playerThatIsMe];
01389
01390 bool accept = (buffer != 0);
01391 if(accept) {
01392 [[me stats] setFlags: intFromPacket(buffer, 4)];
01393 [notificationCenter postNotificationName:@"SP_LOGIN_ACCEPTED" object:self userInfo:me];
01394 } else {
01395 [notificationCenter postNotificationName:@"SP_LOGIN_NOT_ACCEPTED" object:self userInfo:nil];
01396 }
01397 }
01398 @catch (NSException * e) {
01399 NSLog(@"ServerReader.handlePacket: SP_LOGIN error");
01400 NSLog([NSString stringWithFormat:@"%@: %@", [e name], [e reason]]);
01401 }
01402 break;
01403 case SP_FLAGS :
01404 @try {
01405 int playerId = buffer;
01406 Player *player = [universe playerWithId:playerId];
01407 [player setFlags: intFromPacket(buffer, 4)];
01408
01409 }
01410 @catch (NSException * e) {
01411 NSLog(@"ServerReader.handlePacket: SP_FLAGS error");
01412 NSLog([NSString stringWithFormat:@"%@: %@", [e name], [e reason]]);
01413 }
01414 break;
01415 case SP_MASK :
01416 @try {
01417 int teamMask = buffer;
01418 [notificationCenter postNotificationName:@"SP_MASK"
01419 object:self userInfo:[NSNumber numberWithInt:teamMask]];
01420 }
01421 @catch (NSException * e) {
01422 NSLog(@"ServerReader.handlePacket: SP_MASK error");
01423 NSLog([NSString stringWithFormat:@"%@: %@", [e name], [e reason]]);
01424 }
01425 break;
01426 case SP_PSTATUS :
01427 @try {
01428 int playerId = buffer;
01429 Player *player = [universe playerWithId:playerId];
01430 int status = buffer;
01431 if([player status] != status) {
01432
01433 [player setStatus:status];
01434 switch(status) {
01435
01436 case PLAYER_EXPLODE :
01437 [player setExplode: 0];
01438
01439
01440 break;
01441 case PLAYER_DEAD :
01442
01443 [player setStatus:PLAYER_EXPLODE];
01444 break;
01445 default :
01446
01447 [player setKills: 0];
01448 break;
01449 }
01450 [notificationCenter postNotificationName:@"SP_PSTATUS" object:self userInfo:player];
01451 }
01452 }
01453 @catch (NSException * e) {
01454 NSLog(@"ServerReader.handlePacket: SP_PSTATUS error");
01455 NSLog([NSString stringWithFormat:@"%@: %@", [e name], [e reason]]);
01456 }
01457 break;
01458 case SP_BADVERSION :
01459 NSLog(@"ServerReader.handlePacket: SP_BADVERSION not implemented");
01460 break;
01461 case SP_HOSTILE :
01462 @try {
01463 int playerId = buffer;
01464 Player *player = [universe playerWithId:playerId];
01465 [player setStickyWar: (buffer)];
01466 [player setHostile:(buffer)];
01467
01468 }
01469 @catch (NSException * e) {
01470 NSLog(@"ServerReader.handlePacket: SP_HOSTILE error");
01471 NSLog([NSString stringWithFormat:@"%@: %@", [e name], [e reason]]);
01472 }
01473 break;
01474 case SP_STATS :
01475 @try {
01476 int playerId = buffer;
01477 Player *player = [universe playerWithId:playerId];
01478 PlayerStats *stats = [player stats];
01479 [stats updateTournamentKills: intFromPacket(buffer, 4)
01480 tournamentLosses: intFromPacket(buffer, 8)
01481 kills: intFromPacket(buffer, 12)
01482 losses: intFromPacket(buffer, 16)
01483 tournamentTicks: intFromPacket(buffer, 20)
01484 tournamentPlanets: intFromPacket(buffer, 24)
01485 tournamentArmiesBombed: intFromPacket(buffer, 28)
01486 starbaseKills: intFromPacket(buffer, 32)
01487 starbaseLosses: intFromPacket(buffer, 36)
01488 armiesBombed: intFromPacket(buffer, 40)
01489 planets: intFromPacket(buffer, 44)
01490 starbaseMaxKills: (double)intFromPacket(buffer, 52) / 100];
01491
01492 FeatureList *fList = [communication featureList];
01493 if([[player ship] type] == SHIP_SB &&
01494 [fList valueForFeature: FEATURE_LIST_SB_HOURS] != FEATURE_OFF) {
01495 [stats setStarbaseTicks: intFromPacket(buffer, 48)];
01496 }
01497 else {
01498 [stats setMaxKills: (double)intFromPacket(buffer, 48) / 100];
01499 }
01500
01501 }
01502 @catch (NSException * e) {
01503 NSLog(@"ServerReader.handlePacket: SP_STATS error");
01504 NSLog([NSString stringWithFormat:@"%@: %@", [e name], [e reason]]);
01505 }
01506 break;
01507 case SP_PL_LOGIN :
01508 @try {
01509 int playerId = buffer;
01510 Player *player = [universe playerWithId:playerId];
01511
01512 PlayerStats *pstats = [player stats];
01513 Rank *oldRank = [pstats rank];
01514 Rank *newRank = [pstats setRankWithId: (buffer)];
01515
01516 if([player isMe] && newRank != oldRank) {
01517
01518 Status *stats = [universe status];
01519 [stats setPromoted: YES];
01520 }
01521 NSString *name = [self stringFromBuffer:buffer startFrom:4 maxLength:16];
01522 [player setName:name];
01523 NSString *monitor = [self stringFromBuffer:buffer startFrom:20 maxLength:16];
01524 [player setMonitor:monitor];
01525 NSString *login = [self stringFromBuffer:buffer startFrom:36 maxLength:16];
01526 [player setLogin:login];
01527
01528 }
01529 @catch (NSException * e) {
01530 NSLog(@"ServerReader.handlePacket: SP_PL_LOGIN error");
01531 NSLog([NSString stringWithFormat:@"%@: %@", [e name], [e reason]]);
01532 }
01533 break;
01534 case SP_RESERVED :
01535 @try {
01536 NSData *sreserved = [NSData dataWithBytes:(buffer+4) length:16];
01537
01538
01539
01540
01541 [notificationCenter postNotificationName:@"SP_RESERVED" object:self userInfo:sreserved];
01542 }
01543 @catch (NSException * e) {
01544 NSLog(@"ServerReader.handlePacket: SP_RESERVED error");
01545 NSLog([NSString stringWithFormat:@"%@: %@", [e name], [e reason]]);
01546 }
01547 break;
01548 case SP_PLANET_LOC :
01549 @try {
01550 Planet *planet = [universe planetWithId:(buffer)];
01551
01552
01553
01554
01555
01556
01557
01558
01559
01560 NSPoint pos;
01561 pos.x = intFromPacket(buffer, 4);
01562 pos.y = intFromPacket(buffer, 8);
01563 [planet setPosition: pos];
01564
01565 NSString *name = [self stringFromBuffer:buffer startFrom:12 maxLength:16];
01566 [planet setName:name];
01567 [planet setNeedsDisplay:YES];
01568
01569 }
01570 @catch (NSException * e) {
01571 NSLog(@"ServerReader.handlePacket: SP_PLANET_LOC error");
01572 NSLog([NSString stringWithFormat:@"%@: %@", [e name], [e reason]]);
01573 }
01574 break;
01575 case SP_UDP_REPLY :
01576 @try {
01577
01578 [self handleUdpReply:buffer];
01579 }
01580 @catch (NSException * e) {
01581 NSLog(@"ServerReader.handlePacket: SP_PLANET_LOC error");
01582 NSLog([NSString stringWithFormat:@"%@: %@", [e name], [e reason]]);
01583 }
01584 break;
01585 case SP_SEQUENCE :
01586 case SP_SC_SEQUENCE :
01587
01588 [self handleSequence:buffer];
01589 break;
01590 case SP_RSA_KEY :
01591 @try {
01592 NSLog(@"ServerReader.handlePacket: RSA verification requested.");
01593 NSData *data = [NSData dataWithBytes:(buffer+4) length:RSA_KEY_SIZE];
01594
01595
01596
01597 [notificationCenter postNotificationName:@"SP_RSA_KEY" object:self userInfo:data];
01598 }
01599 @catch (NSException * e) {
01600 NSLog(@"ServerReader.handlePacket: SP_RSA_KEY error");
01601 NSLog([NSString stringWithFormat:@"%@: %@", [e name], [e reason]]);
01602 }
01603 break;
01604 case SP_MOTD_PIC :
01605 NSLog(@"ServerReader.handlePacket: SP_MOTD_PIC not implemented");
01606 break;
01607 case SP_SHIP_CAP :
01608 @try {
01609
01610 int shipType = shortFromPacket(buffer, 2);
01611 Ship *ship = [universe shipOfType:shipType];
01612
01613 [ship setTorpSpeed: shortFromPacket(buffer, 4)];
01614 [ship setPhaserDamage: shortFromPacket(buffer, 6)];
01615 [ship setMaxSpeed: intFromPacket(buffer, 8)];
01616 [ship setMaxFuel: intFromPacket(buffer, 12)];
01617 [ship setMaxShield: intFromPacket(buffer, 16)];
01618 [ship setMaxDamage: intFromPacket(buffer, 20)];
01619 [ship setMaxWeaponTemp: intFromPacket(buffer, 24)];
01620 [ship setMaxEngineTemp: intFromPacket(buffer, 28)];
01621 [ship setWidth: shortFromPacket(buffer, 30)];
01622 [ship setHeight: shortFromPacket(buffer, 32)];
01623 [ship setMaxArmies: shortFromPacket(buffer, 34)];
01624
01625 [notificationCenter postNotificationName:@"SP_SHIP_CAP" object:self userInfo:ship];
01626 }
01627 @catch (NSException * e) {
01628 NSLog(@"ServerReader.handlePacket: SP_SHIP_CAP error");
01629 NSLog([NSString stringWithFormat:@"%@: %@", [e name], [e reason]]);
01630 }
01631 break;
01632 case SP_S_REPLY :
01633 @try {
01634 int reply = buffer;
01635 switch(reply) {
01636 case SPK_VOFF :
01637 if([communication shortVersion] == SHORTVERSION && ![communication receiveShort]) {
01638 NSLog(@"ServerReader.handlePacket: Using Short Packet Version 1.");
01639
01640 [communication setShortVersion: OLDSHORTVERSION];
01641
01642
01643 [notificationCenter postNotificationName:@"SP_S_REPLY_SPK_OLD" object:self
01644 userInfo:[NSNumber numberWithInt:SPK_VON]];
01645 }
01646 else {
01647 [communication setReceiveShort: NO];
01648
01649
01650
01651 [notificationCenter postNotificationName:@"SP_S_REPLY_SPK_VOFF" object:self
01652 userInfo:[NSNumber numberWithInt:COMM_UPDATE]];
01653 }
01654 break;
01655 case SPK_VON:
01656 [communication setReceiveShort: YES];
01657
01658
01659
01660
01661
01662
01663
01664
01665
01666
01667 [notificationCenter postNotificationName:@"SP_S_REPLY_SPK_VON" object:self
01668 userInfo:[NSNumber numberWithInt:SPK_SALL]];
01669 NSLog(@"ServerReader.handlePacket: Receiving Short Packet Version ");
01670 break;
01671 case SPK_THRESHOLD:
01672 break;
01673 default:
01674 NSLog(@"ServerReader.handlePacket: Unknown response packet value short-req ");
01675 break;
01676 }
01677 }
01678 @catch (NSException * e) {
01679 NSLog(@"ServerReader.handlePacket: SP_S_REPLY error");
01680 NSLog([NSString stringWithFormat:@"%@: %@", [e name], [e reason]]);
01681 }
01682 break;
01683 case SP_S_MESSAGE :
01684 @try {
01685
01686
01687 NSMutableString *message = [NSString stringWithString: @" -> "];
01688 int from = buffer & 0xFF;
01689 if(from > [universe playerCount]) {
01690 from = 255;
01691 }
01692 if(from == 255) {
01693 message = [NSString stringWithString: @"GOD->"];
01694 }
01695 else {
01696 Player *player = [universe playerWithId:from];
01697 message = [NSString stringWithFormat:@" %@->", [player mapChars]];
01698 }
01699
01700
01701 Player *me = [universe playerThatIsMe];
01702 Team* myTeam = [me team];
01703 switch(buffer[1] & (TEAM | INDIV | ALL)) {
01704 case TEAM :
01705 [message appendString:[myTeam abbreviation]];
01706 break;
01707 case INDIV :
01708 [message appendString:[me mapChars]];
01709 break;
01710 default :
01711 [message appendString: @"ALL"];
01712 break;
01713 }
01714
01715
01716 [message appendString:[self stringFromBuffer:buffer startFrom:5 maxLength:79]];
01717 [notificationCenter postNotificationName:@"SP_S_MESSAGE" object:self userInfo:message];
01718 }
01719 @catch (NSException * e) {
01720 NSLog(@"ServerReader.handlePacket: SP_S_MESSAGE error");
01721 NSLog([NSString stringWithFormat:@"%@: %@", [e name], [e reason]]);
01722 }
01723 break;
01724 case SP_S_WARNING :
01725 @try {
01726 if(swarningHandler == nil) {
01727 swarningHandler = [[ShortPacketWarningHandler alloc] init];
01728 }
01729
01730 NSLog(@"ServerReader.handlePacket: SP_S_WARNING passing to ShortPacketWarningHandler");
01731 [swarningHandler handleSWarning:buffer];
01732 }
01733 @catch (NSException * e) {
01734 NSLog(@"ServerReader.handlePacket: SP_S_WARNING error");
01735 NSLog([NSString stringWithFormat:@"%@: %@", [e name], [e reason]]);
01736 }
01737 break;
01738 case SP_S_YOU :
01739 @try {
01740 int ghostSlot = ([communication ghostSlot] == -1) ? buffer[1] : [communication ghostSlot];
01741 Player *me;
01742 if (ghostSlot == -1) {
01743 int playerId = buffer;
01744 me = [universe playerWithId:playerId];
01745 } else {
01746 me = [universe playerWithId:ghostSlot];
01747 }
01748
01749 [me updateHostile: buffer
01750 stickyWar: buffer
01751 armies: buffer
01752 flags: intFromPacket(buffer, 8)
01753 whyDead: buffer
01754 whoKilledMe: buffer
01755 thisIsMe: YES];
01756
01757 if(([me flags] & PLAYER_PLOCK) != 0) {
01758 if (([me flags] & PLAYER_OBSERV) != 0) {
01759 [[universe status] setObserver:YES];
01760 }
01761 else {
01762 [[universe status] setObserver:NO];
01763 }
01764 }
01765 else {
01766 [[universe status] setObserver:NO];
01767 }
01768 [notificationCenter postNotificationName:@"SP_S_YOU" object:self userInfo:me];
01769 }
01770 @catch (NSException * e) {
01771 NSLog(@"ServerReader.handlePacket: SP_S_YOU error");
01772 NSLog([NSString stringWithFormat:@"%@: %@", [e name], [e reason]]);
01773 }
01774 break;
01775 case SP_S_YOU_SS :
01776 @try {
01777 Player* me = [universe playerThatIsMe];
01778
01779
01780 if(me == nil) {
01781 return YES;
01782 }
01783
01784 [me updateDamage: shortFromPacket(buffer, 2)
01785 shieldStrenght: shortFromPacket(buffer, 4)
01786 fuel: shortFromPacket(buffer, 6)
01787 engineTemp: (short)shortFromPacket(buffer, 8)
01788 weaponsTemp: (short)shortFromPacket(buffer, 10)
01789 thisIsMe: YES];
01790
01791
01792 FeatureList *fList = [communication featureList];
01793 if([fList valueForFeature: FEATURE_LIST_SELF_8FLAGS] != FEATURE_OFF) {
01794 [me setFlags: (([me flags] & 0xFFFFFF00) | (buffer & 0xFF))];
01795 }
01796 else if([fList valueForFeature: FEATURE_LIST_SELF_8FLAGS2] != FEATURE_OFF) {
01797 int new_flags = [me flags] & ~(PLAYER_SHIELD | PLAYER_REPAIR | PLAYER_CLOAK
01798 | PLAYER_GREEN | PLAYER_YELLOW | PLAYER_RED | PLAYER_TRACT | PLAYER_PRESS);
01799
01800 int pad1 = buffer & 0xFF;
01801
01802 new_flags |= ((pad1 & PLAYER_SHIELD) | (pad1 & PLAYER_REPAIR)
01803 | ((pad1 & (PLAYER_CLOAK << 2)) >> 2) | ((pad1 & (PLAYER_GREEN << 7)) >> 7)
01804 | ((pad1 & (PLAYER_YELLOW << 7)) >> 7) | ((pad1 & (PLAYER_RED << 7)) >> 7)
01805 | ((pad1 & (PLAYER_TRACT << 15)) >> 15) | ((pad1 & (PLAYER_PRESS << 15)) >> 15));
01806
01807 [me setFlags: new_flags];
01808 }
01809 [notificationCenter postNotificationName:@"SP_S_YOU_SS" object:self userInfo:me];
01810 }
01811 @catch (NSException * e) {
01812 NSLog(@"ServerReader.handlePacket: SP_S_YOU_SS error");
01813 NSLog([NSString stringWithFormat:@"%@: %@", [e name], [e reason]]);
01814 }
01815 break;
01816 case SP_S_PLAYER :
01817 @try {
01818
01819 [self handleVPlayer:buffer];
01820 }
01821 @catch (NSException * e) {
01822 NSLog(@"ServerReader.handlePacket: SP_S_PLAYER error");
01823 NSLog([NSString stringWithFormat:@"%@: %@", [e name], [e reason]]);
01824 }
01825 break;
01826 case SP_PING :
01827 @try {
01828 int response = (buffer);
01829 [communication setPing:YES withResponse:response];
01830
01831 PingStats *pingStats = [communication pingStats];
01832
01833 [pingStats setLag: (short)shortFromPacket(buffer, 2)];
01834 [pingStats setTotalLossServerToClient:(buffer & 0xFF)
01835 ClientToServer:(buffer & 0xFF)];
01836 [pingStats setIncrementalLossServerToClient:(buffer & 0xFF)
01837 ClientToServer:(buffer & 0xFF)];
01838 [pingStats calculateLag];
01839 [notificationCenter postNotificationName:@"SP_PING" object:self userInfo:pingStats];
01840 }
01841 @catch (NSException * e) {
01842 NSLog(@"ServerReader.handlePacket: SP_PING error");
01843 NSLog([NSString stringWithFormat:@"%@: %@", [e name], [e reason]]);
01844 }
01845 break;
01846 case SP_S_TORP :
01847 case SP_S_8_TORP :
01848 @try {
01849 [self handleVTorp:buffer];
01850 }
01851 @catch (NSException * e) {
01852 NSLog(@"ServerReader.handlePacket: SP_S_TORP error");
01853 NSLog([NSString stringWithFormat:@"%@: %@", [e name], [e reason]]);
01854 }
01855 break;
01856 case SP_S_TORP_INFO :
01857 @try {
01858 [self handleVTorpInfo:buffer];
01859 }
01860 @catch (NSException * e) {
01861 NSLog(@"ServerReader.handlePacket: SP_S_TORP_INFO error");
01862 NSLog([NSString stringWithFormat:@"%@: %@", [e name], [e reason]]);
01863 }
01864 break;
01865 case SP_S_PLANET :
01866 @try {
01867 [self handleVPlanet:buffer];
01868 }
01869 @catch (NSException * e) {
01870 NSLog(@"ServerReader.handlePacket: SP_S_PLANET error");
01871 NSLog([NSString stringWithFormat:@"%@: %@", [e name], [e reason]]);
01872 }
01873 break;
01874 case SP_S_PHASER :
01875 @try {
01876 [self handleVPhaser:buffer];
01877 }
01878 @catch (NSException * e) {
01879 NSLog(@"ServerReader.handlePacket: SP_S_PHASER error");
01880 NSLog([NSString stringWithFormat:@"%@: %@", [e name], [e reason]]);
01881 }
01882 break;
01883 case SP_S_KILLS :
01884 @try {
01885 int player_index = 0;
01886 Player *player;
01887 int data_pos = 2;
01888 int numofkills = buffer & 0xFF;
01889
01890 for(int p = 0; p < numofkills; ++p, data_pos += 2) {
01891 player_index = buffer[data_pos + 1] >> 2;
01892 player = [universe playerWithId:player_index];
01893 [player setKills: (float)(buffer & 0xFF | ((buffer & 0x03) << 8)) / 100];
01894 [notificationCenter postNotificationName:@"SP_S_KILLS" object:self userInfo:player];
01895 }
01896 }
01897 @catch (NSException * e) {
01898 NSLog(@"ServerReader.handlePacket: SP_S_KILLS error");
01899 NSLog([NSString stringWithFormat:@"%@: %@", [e name], [e reason]]);
01900 }
01901 break;
01902 case SP_S_STATS :
01903 @try {
01904 Player *player = [universe playerWithId:buffer];
01905 PlayerStats *stats = [player stats];
01906
01907 [stats updateTournamentKills:shortFromPacket(buffer, 4)
01908 tournamentLosses:shortFromPacket(buffer, 6)
01909 kills:shortFromPacket(buffer, 8)
01910 losses:shortFromPacket(buffer, 10)
01911 tournamentTicks:intFromPacket(buffer, 12)
01912 tournamentPlanets:shortFromPacket(buffer, 2)
01913 tournamentArmiesBombed:intFromPacket(buffer, 16)
01914 starbaseKills:shortFromPacket(buffer, 24)
01915 starbaseLosses:shortFromPacket(buffer, 26)
01916 armiesBombed:shortFromPacket(buffer, 28)
01917 planets:shortFromPacket(buffer, 30)
01918 starbaseMaxKills:intFromPacket(buffer, 32) / 100];
01919
01920 FeatureList *fList = [communication featureList];
01921
01922 if([[player ship] type] == SHIP_SB && [fList valueForFeature: FEATURE_LIST_SB_HOURS] != FEATURE_OFF) {
01923 [stats setStarbaseTicks: intFromPacket(buffer, 48)];
01924 }
01925 else {
01926 [stats setMaxKills: (double)intFromPacket(buffer, 48) / 100];
01927 }
01928 [notificationCenter postNotificationName:@"SP_S_STATS" object:self userInfo:player];
01929 }
01930 @catch (NSException * e) {
01931 NSLog(@"ServerReader.handlePacket: SP_S_STATS error");
01932 NSLog([NSString stringWithFormat:@"%@: %@", [e name], [e reason]]);
01933 }
01934 break;
01935 case SP_FEATURE :
01936 @try {
01937 FeatureList *fList = [communication featureList];
01938
01939 char type = (char)buffer[1];
01940 int arg1 = (int)buffer[2];
01941 int arg2 = (int)buffer[3];
01942 int value = intFromPacket(buffer, 4);
01943 NSString *name = [self stringFromBuffer:buffer startFrom:8 maxLength:80];
01944 [fList checkFeature:name withType:type withArg1:arg1 withArg2:arg2 withValue:value];
01945 [notificationCenter postNotificationName:@"SP_FEATURE" object:self userInfo:nil];
01946 }
01947 @catch (NSException * e) {
01948 NSLog(@"ServerReader.handlePacket: SP_FEATURE error");
01949 NSLog([NSString stringWithFormat:@"%@: %@", [e name], [e reason]]);
01950 }
01951 break;
01952 case SP_BITMAP :
01953 NSLog(@"ServerReader.handlePacket: SP_BITMAP not implemented");
01954 break;
01955 }
01956
01957
01958
01959
01960
01961 return YES;
01962 }
01963
01964 - (NSString*) stringFromBuffer:(char*)buffer startFrom:(int)start maxLength:(int)max {
01965
01966
01967 NSString *line = [NSString stringWithUTF8String:(buffer + start)];
01968
01969 return line;
01970
01971
01972
01973
01974
01975
01976
01977
01978
01979
01980
01981
01982
01983
01984
01985 }
01986
01987
01988
01989 @end