00001
00002
00003
00004
00005
00006
00007
00008
00009 #import "ServerReaderUdp.h"
00010
00011
00012 @implementation ServerReaderUdp
00013
00014 ONUDPSocket *udpSocket;
00015
00016 - (id) init {
00017 self = [super init];
00018 if (self != nil) {
00019 udpSocket = nil;
00020 udpStats = nil;
00021 }
00022 return self;
00023 }
00024
00025 - (id)initWithUniverse:(Universe*)newUniverse communication:(Communication*)comm socket:(ONUDPSocket *)socket udpStats:(UdpStats*)stats{
00026 self = [self initWithUniverse:newUniverse communication:comm];
00027 if (self != nil) {
00028 udpStats = stats;
00029 udpSocket = socket;
00030 }
00031 return self;
00032 }
00033
00034 - (void) close {
00035 [udpSocket release];
00036 udpSocket = nil;
00037 }
00038
00039 -(UdpStats*)udpStats {
00040 return udpStats;
00041 }
00042
00043 - (NSData *) doRead {
00044
00045
00046 NSMutableData *data = [[NSMutableData dataWithLength: SRV_UDP_MAX_DATA_LENGTH] autorelease];
00047
00048
00049
00050
00051
00052 [data setLength: SRV_UDP_MAX_DATA_LENGTH];
00053
00054 @try {
00055 int length = [udpSocket readBytes: SRV_UDP_MAX_DATA_LENGTH
00056 intoBuffer: [data mutableBytes]];
00057 [data setLength: length];
00058 }
00059 @catch (NSException * e) {
00060 NSLog(@"ServerReaderUdp.doRead: Timed out waiting for UDP response from server");
00061
00062 [communication setCommMode: COMM_TCP];
00063 [communication setCommStatus: STAT_CONNECTED];
00064 NSLog(@"ServerReaderUdp.doRead: Should connected to server's TCP port");
00065 [notificationCenter postNotificationName:@"SP_UDP_SWITCHED_TO_TCP" object:self userInfo:nil];
00066
00067 return nil;
00068 }
00069
00070
00071 NSLog([NSString stringWithFormat: @"ServerReaderUpd.doRead got packet from %@:%d:\n",
00072 [udpSocket remoteAddressHost], [udpSocket remoteAddressPort]]);
00073
00074 return data;
00075 }
00076
00077 - (bool) handlePacket:(int)ptype withSize:(int)size inBuffer:(char *)buffer {
00078
00079 [communication increasePacketsReceived];
00080 return [super handlePacket:ptype withSize:size inBuffer:buffer];
00081 }
00082
00083
00084 - (void) handleSequence:(char *) buffer {
00085 [udpStats increaseUdpTotalBy:1];
00086 [udpStats increaseRecentCountBy:1];
00087
00088
00089 if (([udpStats udpTotal] & 0xFF) == 0) {
00090 [notificationCenter postNotificationName:@"SRU_UDP_STATS_CHANGED"
00091 object:self userInfo:udpStats];
00092 }
00093
00094
00095
00096 int new_sequence = shortFromPacket(buffer, 2);
00097
00098 if ([udpStats sequence] > 65000 && new_sequence < 1000) {
00099
00100 [udpStats setSequence: (([udpStats sequence] + 65536) & 0xFFFF0000) | new_sequence];
00101 }
00102 else {
00103
00104 new_sequence |= ([udpStats sequence] & 0xFFFF0000);
00105
00106 if (new_sequence > [udpStats sequence]) {
00107
00108 if (new_sequence != [udpStats sequence] + 1) {
00109 int diff = (new_sequence - [udpStats sequence]) - 1;
00110 [udpStats increaseUdpDroppedBy:diff];
00111 [udpStats increaseUdpTotalBy:diff];
00112 [udpStats increaseRecentDroppedBy:diff];
00113 [udpStats increaseRecentCountBy:diff];
00114 [notificationCenter postNotificationName:@"SRU_UDP_STATS_LOST_SOME"
00115 object:self userInfo:udpStats];
00116 }
00117 [udpStats setSequence: new_sequence];
00118
00119 if ([communication shortVersion] == COMM_SHORTVERSION && [communication receiveShort]) {
00120 Player *me = [universe playerThatIsMe];
00121 [me setFlags: ([me flags] & 0xFFFF00FF) | (buffer & 0xFF) << 8];
00122 }
00123 else {
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135 [communication decreasePacketsReceived];
00136 NSLog(@"ServerReaderUdp.handleSequence: rejected out of sequence packet");
00137 }
00138 }
00139 if ([udpStats recentCount] > UDP_RECENT_INTR) {
00140
00141
00142 [udpStats setUdpRecentDropped:[udpStats recentDropped]];
00143 [udpStats setRecentCount:0];
00144 [udpStats setRecentDropped:0];
00145 [notificationCenter postNotificationName:@"SRU_UDP_STATS_CHANGED"
00146 object:self userInfo:udpStats];
00147 }
00148 }
00149 }
00150
00151
00152 @end