Hello out there,
My name’s Troy and I’m working along with Franky to make a game over the summer. If you’re thinking about working on a game or otherĀ programming project I’d highly recommend working long with someone else or in a group. At least for me being able to bounce ideas off other people and it’s a must if you’re new to programming or the language. It’s easy to get the wrong idea of how a language is working under the hood and it’s better to have a friend point it out to you rather than spending hours hitting your head against a wall.
Case in point, I’ve been racking my brain to get collision to work for a little test game in Lua pretty much all day today.
Hey Everyone,
So heres this really compact JSON Parser I found which I know will help a lot of people who just want to get a JSON Parser in their code without too much work.
JSON++
Let me know if this helps it did for me.
-Frank N.-
Hello,
[The Code can be used with flash to create an online game once I post the source code!]
I’ve been away from this forum for so long it looks like crap so I’m gonna change a few things and add this project into it.
I’m developing an HTML5 Websockets Server using its standard which is new and isn’t really hard I’ll post notes about what I’m doing here.
Notes*:
Using epoll/kqueue in a linux environment/bsd environment.
Here is a link to look up the polling system it uses a complexity of O(1). It is kernel based so you don’t have to manage all the descriptors.
EPOLL
Also here is the setup I’m trying to accomplish with extra Database management classes.
EPOLL Asynchronous management
As far as Websocket protocols go you can go here and research that I’ll have more information later about this as I progress.
HTML5 WebSocket Protocol
When reading bytes from the client accept it as a unsigned char* (C/C++). It sends UTF8 data so you can get away with signed but when sending out information you might want to look at using unsigned char* because the md5 hash is unsigned 16 byte cstring.
*Update*
void Parser::Execute(void * arg){
//Process Data
for(;;){
unsigned char * out;
unsigned int Key1_int, Key2_int, out_size = 0;
unsigned long n = 0,d = 0;
std::istringstream Converter;
std::string NL = "\r\n";
std::string Key1 = "Sec-WebSocket-Key1: ";
std::string Key2 = "Sec-WebSocket-Key2: ";
std::string Token;
std::string Key1_num, Key2_num;
std::string const output = "HTTP/1.1 101 WebSocket Protocol Handshake\r\n";
output += "Upgrade: WebSocket\r\n";
output += "Connection: Upgrade\r\n";
output += "Sec-WebSocket-Origin: http://tempostudios.com\r\n";
output += "Sec-WebSocket-Location: ws://fserver.lndp.net:1035/\r\n\r\n";
size_t Key1_loc,Key2_loc,Token_loc;
//Semaphore Wait Call
Data->wait();
//Grab Data from the queue.
tempData = Data->get();
//Try and locate Key's for STRING(Key1) and STRING(Key2)
Key1_loc = tempData.buffer.find(Key1);
Key2_loc = tempData.buffer.find(Key2);
if(Key1_loc!=std::string::npos && Key1_loc!=std::string::npos){//If found in Data then continue
//Found!
//Grab the variables we need from data from the positions that they were found at.
Key1 = tempData.buffer.substr(Key1_loc+Key1.length(),tempData.buffer.find(NL,Key1_loc)-(Key1_loc+Key1.length()));
Key2 = tempData.buffer.substr(Key2_loc+Key2.length(),tempData.buffer.find(NL,Key2_loc)-(Key2_loc+Key2.length()));
Token = tempData.buffer.substr(tempData.buffer.find(NL+NL)+std::string(NL+NL).length(), 8);
//Convert Key1 and Key2 into a unsigned long should only be a unsigned int but for safety reasons..
for(int i=0;i<Key1.length();i++){//Concatenate the numbers only and increment 'd' on every space.
switch(Key1.at(i)){
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
Key1_num += Key1.at(i);
break;
case ' ':
d++;
break;
default:
NULL;
}
}
//Use isstream to read in STRING(Key1_num) and then output a number into 'n'
Converter.clear();
Converter.str(Key1_num);
Converter>>n;
//Divide 'n' by 'd' to get the 32 bit int we need for the MD5 Hash.
Key1_int = n/d;
d = 0;
n = 0;
for(int i=0;i<Key2.length();i++){//Concatenate the numbers only and increment 'd' on every space.
switch(Key2.at(i)){
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
Key2_num += Key2.at(i);
break;
case ' ':
d++;
break;
default:
//do nothing
NULL;
}
}
//Use isstream to read in STRING(Key2_num) and then output a number into 'n'
Converter.clear();
Converter.str(Key2_num);
Converter>>n;
//Divide 'n' by 'd' to get the 32 bit int we need for the MD5 Hash.
Key2_int = n/d;
//Pack both 32bit numbers into the first 8 bytes of 'buf'
unsigned char buf[17];
buf[0] = (Key1_int&0xff000000) >> 24;
buf[1] = (Key1_int&0x00ff0000) >> 16;
buf[2] = (Key1_int&0x0000ff00) >> 8;
buf[3] = Key1_int&0xff;
buf[4] = (Key2_int&0xff000000) >> 24;
buf[5] = (Key2_int&0x00ff0000) >> 16;
buf[6] = (Key2_int&0x0000ff00) >> 8;
buf[7] = Key2_int&0xff;
//Concatenate the Token into the next 8 bytes.
memcpy(&buf[8], (unsigned char*)Token.c_str() ,8);
//Add NULL byte to set end of string.
buf[16] = 0x0;
unsigned char hash_encKey[17];
//MD5 'buf' and put it inside 'hash_encKey'
memcpy(hash_encKey,MD5(buf,16).getDigest(), 16);
//Add NULL byte to set end of string.
hash_encKey[16] = 0x0;
//Allocate an unsigned char with a size of 'output.length()+16'
out = new unsigned char[output.length()+16];
out_size = output.length()+16;
//Copy in the standard output for the handshake
memcpy(out, output.c_str(), output.length());
//Copy in the MD5 hash we got after we hashed 'buf'
memcpy(out+output.length(), hash_encKey, 16);
//Send out 'out' and check for errors.
if(send(tempData.socket, out, out_size,0)<0){
std::cout<<"Error Sending"<<std::endl;
}
//Deallocate 'out' keep memory leaks out of the equation!
delete[] out;
}else{
//Grab the first byte and delcare the 'type'
char type = tempData.buffer.at(0);
int i = 1;
switch((type&0x80)){//bitwise AND type and 0x80
case 0x80://if 0x80 it is a server message
//Need to finish this
break;
case 0x00: //RECV A Message from server
std::string recv;
//Check to see if it's just not an empty string.
if(tempData.buffer.at(1)!=((char)0xff)){//if not then continue.
for(i=1; i<tempData.buffer.length();i++){//loop through the whole STRING till 0xff is found. Which means end of string.
if(tempData.buffer.at(i)!=((char)0xff)){
recv += tempData.buffer.at(i);//Append character to 'recv'
}else{
break; //We hit a 0xff break out of loop.
}
}
//You can now output 'recv'
std::cout<<"Recv: "<<recv<<std::endl;
//Let's us create a example message. A message is encased by a '0x00' and '0xff'
//Due to the reasoning of a STRING we need to declare the size of the const char* we declare so it doesn't stop at '0x00' at the beginning of the string.
std::string hello = std::string("\x00Hello World!\xff", 14);
//Send out 'hello' and check for errors.
if(send(tempData.socket, hello.c_str(), hello.length(), 0)<0){
std::cout<<"Error Sending"<<std::endl;
}
}
break;
}
}
}
}
-Frank N.-
void Parser::Execute(void * arg){
//Process Data
for(;;){
unsigned char * out;
unsigned int Key1_int, Key2_int, out_size = 0;
unsigned long n = 0,d = 0;
std::istringstream Converter;
std::string NL = "\r\n";
std::string Key1 = "Sec-WebSocket-Key1: ";
std::string Key2 = "Sec-WebSocket-Key2: ";
std::string Token;
std::string Key1_num, Key2_num;
std::string const output = "HTTP/1.1 101 WebSocket Protocol Handshake\r\n";
output += "Upgrade: WebSocket\r\n";
output += "Connection: Upgrade\r\n";
output += "Sec-WebSocket-Origin: http://tempostudios.com\r\n";
output += "Sec-WebSocket-Location: ws://fserver.lndp.net:1035/\r\n\r\n";
size_t Key1_loc,Key2_loc,Token_loc;
//Semaphore Wait Call
Data->wait();
//Grab Data from the queue.
tempData = Data->get();
//Try and locate Key's for STRING(Key1) and STRING(Key2)
Key1_loc = tempData.buffer.find(Key1);
Key2_loc = tempData.buffer.find(Key2);
if(Key1_loc!=std::string::npos && Key1_loc!=std::string::npos){//If found in Data then continue
//Found!
//Grab the variables we need from data from the positions that they were found at.
Key1 = tempData.buffer.substr(Key1_loc+Key1.length(),tempData.buffer.find(NL,Key1_loc)-(Key1_loc+Key1.length()));
Key2 = tempData.buffer.substr(Key2_loc+Key2.length(),tempData.buffer.find(NL,Key2_loc)-(Key2_loc+Key2.length()));
Token = tempData.buffer.substr(tempData.buffer.find(NL+NL)+std::string(NL+NL).length(), 8);
//Convert Key1 and Key2 into a unsigned long should only be a unsigned int but for safety reasons..
for(int i=0;i<Key1.length();i++){//Concatenate the numbers only and increment 'd' on every space.
switch(Key1.at(i)){
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
Key1_num += Key1.at(i);
break;
case ' ':
d++;
break;
default:
NULL;
}
}
//Use isstream to read in STRING(Key1_num) and then output a number into 'n'
Converter.clear();
Converter.str(Key1_num);
Converter>>n;
//Divide 'n' by 'd' to get the 32 bit int we need for the MD5 Hash.
Key1_int = n/d;
d = 0;
n = 0;
for(int i=0;i<Key2.length();i++){//Concatenate the numbers only and increment 'd' on every space.
switch(Key2.at(i)){
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
Key2_num += Key2.at(i);
break;
case ' ':
d++;
break;
default:
//do nothing
NULL;
}
}
//Use isstream to read in STRING(Key2_num) and then output a number into 'n'
Converter.clear();
Converter.str(Key2_num);
Converter>>n;
//Divide 'n' by 'd' to get the 32 bit int we need for the MD5 Hash.
Key2_int = n/d;
//Pack both 32bit numbers into the first 8 bytes of 'buf'
unsigned char buf[17];
buf[0] = (Key1_int&0xff000000) >> 24;
buf[1] = (Key1_int&0x00ff0000) >> 16;
buf[2] = (Key1_int&0x0000ff00) >> 8;
buf[3] = Key1_int&0xff;
buf[4] = (Key2_int&0xff000000) >> 24;
buf[5] = (Key2_int&0x00ff0000) >> 16;
buf[6] = (Key2_int&0x0000ff00) >> 8;
buf[7] = Key2_int&0xff;
//Concatenate the Token into the next 8 bytes.
memcpy(&buf[8], (unsigned char*)Token.c_str() ,8);
//Add NULL byte to set end of string.
buf[16] = 0x0;
unsigned char hash_encKey[17];
//MD5 'buf' and put it inside 'hash_encKey'
memcpy(hash_encKey,MD5(buf,16).getDigest(), 16);
//Add NULL byte to set end of string.
hash_encKey[16] = 0x0;
//Allocate an unsigned char with a size of 'output.length()+16'
out = new unsigned char[output.length()+16];
out_size = output.length()+16;
//Copy in the standard output for the handshake
memcpy(out, output.c_str(), output.length());
//Copy in the MD5 hash we got after we hashed 'buf'
memcpy(out+output.length(), hash_encKey, 16);
//Send out 'out' and check for errors.
if(send(tempData.socket, out, out_size,0)<0){
std::cout<<"Error Sending"<<std::endl;
}
//Deallocate 'out' keep memory leaks out of the equation!
delete[] out;
}else{
//Grab the first byte and delcare the 'type'
char type = tempData.buffer.at(0);
int i = 1;
switch((type&0x80)){//bitwise AND type and 0x80
case 0x80://if 0x80 it is a server message
//Need to finish this
break;
case 0x00: //RECV A Message from server
std::string recv;
//Check to see if it's just not an empty string.
if(tempData.buffer.at(1)!=((char)0xff)){//if not then continue.
for(i=1; i<tempData.buffer.length();i++){//loop through the whole STRING till 0xff is found. Which means end of string.
if(tempData.buffer.at(i)!=((char)0xff)){
recv += tempData.buffer.at(i);//Append character to 'recv'
}else{
break; //We hit a 0xff break out of loop.
}
}
//You can now output 'recv'
std::cout<<"Recv: "<<recv<<std::endl;
//Let's us create a example message. A message is encased by a '0x00' and '0xff'
//Due to the reasoning of a STRING we need to declare the size of the const char* we declare so it doesn't stop at '0x00' at the beginning of the string.
std::string hello = std::string("\x00Hello World!\xff", 14);
//Send out 'hello' and check for errors.
if(send(tempData.socket, hello.c_str(), hello.length(), 0)<0){
std::cout<<"Error Sending"<<std::endl;
}
}
break;
}
}
}
}
Hello Again,
Alright so after having some time I have been coming up with a dbf reader made in C. It’s cross-platform only thing now I’m debating the way it stores the information I was using linked lists but that will cause some major issues later in iteration through the rows in the database. Anyways If you have your own style and what not you can use this to read in the information the only thing that would change is the “getRows()” Function. It will only store the first column of data from each row. It’s very precise as I can see so far taking into consideration some +1 and -1 for positioning the correct byte because of programming scheme in place. Anyways maybe this will help someone out I created this myself in about 2 days it was just a pain with all the pointer arithmatic but oh well have fun with it.
File: DBF Reader in C
The File is text based so no worries of an executable with malicious code or anything. Also is contained within one file I understand the flaws of the design but it was just for testing purposes really so I didn’t feel it necessary to seperate it for different development areas keeps things quick and easy.
Compile and Run then insert a ArcGIS DBF File and see if you can get the same information from it as I do. To check its precision open the DBF File inside excel/or other spreadsheet reader and go from there.
-Frank N.-