ID:1299098
 
(See the best response by Nadrew.)
I want to make a BYOND library where people can use it to communicate with their game through an iPhone app. Some use cases would be an external minimap, an external way to call verbs, moderating, chatting.

I'm trying to send messages to world/Topic from my iPhone using Objective-C. I'm trying to port over the php code in the following link: http://pastebin.com/T9MW4u5p. The php code works great. I don't understand php well enough or BYOND's socket communication.

php code:

$str = "?TestString";
$query = "\x00\x83" . pack('n', strlen($str) + 6) . "\x00\x00\x00\x00\x00" . $str . "\x00";


Objective-C code:

char bytes[] = "\x00\x83##\x00\x00\x00\x00\x00?TestString\x00"

## = placeholders for what ever pack() is doing

I'm not certain what pack() is doing in php and I'm assuming I've got it set up right other than that.

I looked into pack() at http://php.net/manual/en/function.pack.php

I'm not sure the objective-c equivalent to pack but if I leave out the characters at ## it will hit world/Topic() with a blank message otherwise it is never hit.
Best response
The format is

\x00\x83[length(message) + 6]\x00\x00\x00\x00\x00[message]\x00
Do you know what encoding to use? According to the php link I posted it says 'n' = unsigned short (always 16 bit, big endian byte order). I'm trying to use NSUTF16BigEndianStringEncoding but that still sends a blank message to Topic().

Here is what I have so far for anyone that is curious:
- (void)sendRequest {
NSString *str = @"?TestString"; char bytes1[] = "\x00\x83";
char bytes2[] = "\x00\x00\x00\x00\x00";
char bytes3[] = "\x00";
NSMutableData *data = [NSMutableData new];
[data appendBytes:bytes1 length:sizeof(bytes1)];
int len = str.length + 6;
[data appendBytes:&len length:sizeof(len)];
[data appendBytes:bytes2 length:sizeof(bytes2)];
[data appendData:[str dataUsingEncoding:NSUTF16BigEndianStringEncoding]];
[data appendBytes:bytes3 length:sizeof(bytes3)];

[socket writeData:data withTimeout:-1 tag:1];
}
In response to Nadrew
Does the length of the message and the message have to be in hex format? Can you post an example of what the string "?Hello" should look like?
The length of the message does indeed have to be in 'n' (or, unsigned short) format. However, the message itself doesn't, since it's just ASCII data and it's translated by the machine anyway.

The function of pack() is simply to convert data into a specific byte format. I'm not quite sure about the objective-c equivalent, but there should be a similar function in its API.
Thank you everyone for your help. I've got communication between the iPhone and the Dream Seeker client working. I'm going to work on an app that people can use with their BYOND projects. And a BYOND project that people can implement into their project to properly communicate with the iPhone.

Here is the code for sending data:

- (void)test {
NSString *str = @"?Hello there! My name is Michael";
uint16_t myInt16AsABigEndianNumber = CFSwapInt16HostToBig(str.length + 6);
NSMutableData *data = [NSMutableData new];
[data appendBytes:"\x00\x83" length:2];
[data appendBytes:&myInt16AsABigEndianNumber length:sizeof(myInt16AsABigEndianNumber)];
[data appendBytes:"\x00\x00\x00\x00\x00" length:5];
[data appendBytes:[str UTF8String] length:str.length];
[data appendBytes:"\x00" length:1];

AsyncSocket *asyncSocket = [[AsyncSocket alloc] initWithDelegate:self];
[asyncSocket connectToHost:@"192.168.1.3" onPort:5000 error:nil];
[asyncSocket writeData:data withTimeout:1 tag:0];
[asyncSocket readDataWithTimeout:-1 tag:0];
[asyncSocket disconnectAfterReadingAndWriting];
}


Here is how you handle a response from BYOND:
//NSData category, self = the NSData that was sent back.

- (NSString *)byondReply {
const unsigned char* bytes = (const unsigned char*)[self bytes];
NSUInteger nbBytes = [self length];
NSUInteger strLen = 2*nbBytes;

NSMutableString* hex = [[NSMutableString alloc] initWithCapacity:strLen];

if([[self charToHex:bytes[0]] isEqualToString:@"00"] || [[self charToHex:bytes[1]] isEqualToString:@"83"]) {
//bit 2 and 3 are the size.
if([[self charToHex:bytes[4]] isEqualToString:@"06"]) {
for(NSUInteger i=5; i < nbBytes; ) {
[hex appendFormat:@"%c", bytes[i]];
++i;
}
}
else if([[self charToHex:bytes[4]] isEqualToString:@"2a"]) { [hex appendString:@"Not implemeted, handle bit 4 == 2a."];
}
}
else [hex appendString:@"Error: Incorrect packet format."];
return hex;
}


If you aren't using ARC be sure to handle the memory management yourself.