IPhone : iOS Game center's multiplayer data not unraveling correctly

on Sunday, February 22, 2015

I am developing an iOS game (iPhone and iPad) and am using the Game Kit's multiplayer methods (using Ray Wenderlich's tutorials: http://www.raywenderlich.com/3276/game-center-tutorial-for-ios-how-to-make-a-simple-multiplayer-game-part-12 and http://www.raywenderlich.com/3325/game-center-tutorial-for-ios-how-to-make-a-simple-multiplayer-game-part-22 , adapting to my own game).


I think I have a problem with the "data" variable. Specifically,



MessageScore *score = (MessageScore*)[data bytes];
NSLog(@"sendScore is going to send %f",score->playerScore);


returns a value of 0 and



MessageScore *message = (Message*)[data bytes];
NSLog(@"message type enumeration: %f",message->messageType);


should only return an integer from 0 to 4 (for 'game play' it should be returning a value of 2 for kMessageTypeScore, its value is assigned in sendScore and sendData below), but it's returning a ridiculously huge number (e.g. 4692750811720056834 or 4751297606875873282). I should note that my NSLog statements (in sendScore and sendData) print correct results.


Explicitly going over what (I believe) is the order of events: (Using device1=iPhone5 and device2=iPad2, both with the most up to date iOS 8.1.3)


device1's score updates. Calls sendScore which calls sendData which sends "data" variable to device2


device2 receives "data" variable in the GameKitHelper method "match" (when I put a NSLog statement here printing the player's score, it is 0 and the messageType is an enormous number). It then calls the MultiplayerNetworking's method "match" which should go down to the line



} else if (message->messageType == kMessageTypeScore) { //value of 2


but since enumerated message->messageType is some outrageously large number, it skips this.


Has anyone experienced this issue before or know how to handle it? I've been at this for days and can't figure out what the problem is.


in MultiplayerNetworking.m



typedef NS_ENUM(NSInteger, MessageType) {
kMessageTypeRandomNumber,
kMessageTypeGameBegin,
kMessageTypeScore,
kMessageTypeGameOver
};
typedef struct {
MessageType messageType;
} Message;
typedef struct {
Message message;
CGFloat playerScore;
} MessageScore;

-(void)sendScore: (CGFloat)playerScore
{
MessageScore message;
message.playerScore = playerScore;
message.message.messageType = kMessageTypeScore; //value = 2
NSData *data = [NSData dataWithBytes:&message length:sizeof(MessageScore)];
[self sendData:data];
MessageScore *messageMove = (MessageScore*)[data bytes];
NSLog(@"sendScore is going to send %f",messageMove->playerScore);
}
- (void)sendData:(NSData*)data
{
NSError *error;
LTGameKitHelper *gameKitHelper = [LTGameKitHelper sharedGameKitHelper];
[gameKitHelper.multiplayerMatch sendDataToAllPlayers:data withDataMode:GKMatchSendDataReliable error:&error];
BOOL success = [gameKitHelper.multiplayerMatch sendDataToAllPlayers:data withDataMode:GKMatchSendDataReliable error:&error];

if (!success) {
NSLog(@"Error sending data:%@", error.localizedDescription);
[self matchEnded];
}
MessageScore *messageMove = (MessageScore*)[data bytes];
NSLog(@"This device sendData is going to send %f",messageMove->playerScore);
}

- (void)match:(GKMatch *)match didReceiveData:(NSData *)data fromPlayer:(NSString *)playerId
{

//1
Message *message = (Message*)[data bytes];
if (message->messageType == kMessageTypeRandomNumber) {
MessageRandomNumber *messageRandomNumber = (MessageRandomNumber*)[data bytes];
NSLog(@"match: kMessageTypeRandomNumber, %i",messageRandomNumber->randomNumber);

BOOL tie = NO;
if (messageRandomNumber->randomNumber == _ourRandomNumber) {
//2
NSLog(@"Tie");
tie = YES;
_ourRandomNumber = arc4random();
[self sendRandomNumber];
} else {
//3
NSDictionary *dictionary = @{playerIdKey : playerId,
randomNumberKey :
@(messageRandomNumber->randomNumber)};
[self processReceivedRandomNumber:dictionary];
}
//4
if (_receivedAllRandomNumbers) {
_isPlayer1 = [self isLocalPlayerPlayer1];
}

if (!tie && _receivedAllRandomNumbers) {
//5
if (_gameState == kGameStateWaitingForRandomNumber) {
_gameState = kGameStateWaitingForStart;
}
[self tryStartGame];
}
} else if (message->messageType == kMessageTypeGameBegin) {
NSLog(@"message->messageType == kMessageTypeGameBegin");
_gameState = kGameStatePlaying;
[self.delegate setCurrentPlayerIndex:[self indexForLocalPlayer]];
[self retrieveAllPlayerAliases];
[self retrieveAllPlayerPhotos];
} else if (message->messageType == kMessageTypeScore) {
NSLog(@"match: kMessageTypeScore");
MessageScore *messageScore = (MessageScore*)[data bytes];
[self.delegate setPlayerScore:[self indexForPlayerWithId:playerId] playerScore:messageScore->playerScore];
} else if(message->messageType == kMessageTypeGameOver) {
NSLog(@"match: kMessageTypeGameOver");
[self.delegate gameOver:[self hasLocalPlayerWon]];
} else if(message->messageType == kMessageTypeHonk) { /*Multiplayer challenge 2*/
NSLog(@"match: kMessageTypeHonk");
[self.delegate playHorn];
} else {
NSLog(@"somehow skipped everything... %ld",message->messageType);
MessageScore *messageMove = (MessageScore*)[data bytes];
[self.delegate setPlayerScore:[self indexForPlayerWithId:playerId] playerScore:messageMove->playerScore];
}
}


//in GameKitHelper.m



- (void)match:(GKMatch *)match didReceiveData:(NSData *)data
fromPlayer:(NSString *)playerID
{
if (_multiplayerMatch != match){
return;
}

MessageScore *messageMove = (MessageScore*)[data bytes];
NSLog(@"Other player is sending a score of %f",messageMove->playerScore);
// messageMove->playerScore = 5;
[_delegate match:match didReceiveData:data
fromPlayer:playerID];
}

0 comments:

Post a Comment