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