int main(int argc, char **argv) {
	printf("compiletime_load started\n");
	printf("#1 i=%d\n", i);
	libInit();
	printf("#2 i=%d\n", i);
	usleep(1000 * 1000);
	printf("#3 i=%d\n", i);
	return 0;
}
Beispiel #2
0
//-----------------------------------------------------------------------------
int main(int argc, char *argv[]) {
	libInit();

	// NOTE: open socket file descriptor
	serverFD = SDLNet_UDP_Open(3490);
	if(!serverFD) {
		fprintf(stderr, "SDLNet_UDP_Open: %s\n", SDLNet_GetError());
		libQuit();
		return -1;
	}

	// NOTE: setup a socket set
	socketSet = SDLNet_AllocSocketSet(1);
	SDLNet_UDP_AddSocket(socketSet, serverFD);
	printf("\nServer open on port: %d\n\n", 3490);

	// NOTE: initialize the player manager
	plManager = initPlayerManager("diamond_collector.db");

	/*
		LISTEN FOR PACKETS
	*/

	for(;;) {
		// NOTE: wait for a connection
		int n = SDLNet_CheckSockets(socketSet, 0);

		if(n==-1) {
			fprintf(stderr, "SDLNet_CheckSockets: %s\n", SDLNet_GetError());
			break;
		} if(!n) {
			// NOTE: if the server doesn't have anything to do then run through
			// a few regular routines
			switch(serverState) {
				case 0x00: {
					if((time(NULL)-lastTimePingsWentOut)>20) {
						// NOTE: if the server is idle in its freetime then start sending out
						// ping packets for the client to respond to
						serverState = 0x01;
						lastTimePingsWentOut = time(NULL);
					}
				} break;
				case 0x01: {
					if(waitingForPong) {
						if(!plManager->pl_indMask[nodeToPing][playerToPing]) {
							playerToPing++;
							waitingForPong = SDL_FALSE;
						} else if((time(NULL)-timeOfPing)>120) {
							// NOTE: if we hear nothing back after 5 secs then disconnect the player
							DB_Player *pl = &plManager->pl_dbInfo[nodeToPing][playerToPing];
							printf("player %s didn't respond to ping logging them out.\n", pl->username);

							// NOTE: set the player state and log the player out
							pl->state = 0x00;

							// NOTE: send a packet out to everyone on this node
							// letting them know that the player is leaving.
							UDPpacket _packet = {};

							/*
							- flag (1) 0x05
							- id   (4)
							====== (5)
							*/

							_packet.maxlen = 0x05; // 5 bytes
							_packet.data = (uint8_t *)malloc(0x05);

							uint8_t offset = 0;

							memset(_packet.data+offset, 0x05, 1);
							offset += 1;
							memcpy(_packet.data+offset, &pl->id, 4);
							offset += 4;

							// NOTE: set the packet length to the offset point
							_packet.len = offset;

							// NOTE: send the packet out to everyone but the player disconnecting
							int i;
							for(i=0; i<PLAYER_MAX; i++) {
								if(!plManager->pl_indMask[pl->node][i])
									continue;

								_packet.address.host = plManager->pl_dbInfo[pl->node][i].host;
								_packet.address.port = plManager->pl_dbInfo[pl->node][i].port;

								if(!SDLNet_UDP_Send(serverFD, -1, &_packet))
									fprintf(stderr, "SDLNet_UDP_Send: %s\n", SDLNet_GetError());
							}

							// NOTE: free the packet
							free(_packet.data);

							// NOTE: save the new player state
							pl_save(plManager, pl);

							if(pl_removePlayer(plManager, pl) != -1) {
								printf("Logout success!\n");
							} else {
								// NOTE: player was never in the players array should
								// probably log this sort of thing
							}

							playerToPing++;
							waitingForPong = SDL_FALSE;
						} else {
							// TODO: keep sending the ping packet
						}
					} else {
						// NOTE: make sure there are people on this node - else go to the
						// next node
						int n = pl_numOnNode(plManager, nodeToPing);

						if(n <= 0) {
							nodeToPing++;
							playerToPing = 0;

							if(nodeToPing==NODE_MAX) {
								nodeToPing = 0;
								serverState = 0x00;
							}

							break;
						}

						// NOTE: if there isn't a player at this point in the pool then
						// go to the next point in the pool
						if(!plManager->pl_indMask[nodeToPing][playerToPing]) {
							playerToPing++;

							if(playerToPing == PLAYER_MAX) {

								nodeToPing++;
								playerToPing = 0;

								if(nodeToPing == NODE_MAX) {
									nodeToPing = 0;
									serverState = 0x00;
								}
							}

							break;
						}

						// NOTE: get the player and send out the ping
						DB_Player *pl = &plManager->pl_dbInfo[nodeToPing][playerToPing];

						// NOTE: send a ping packet
						uint8_t flag = 0x0A;
						UDPpacket _packet = {};

						_packet.data = &flag;

						_packet.len = 1;
						_packet.maxlen = 1;

						_packet.address.host = pl->host;
						_packet.address.port = pl->port;

						if(!SDLNet_UDP_Send(serverFD, -1, &_packet))
							fprintf(stderr, "SDLNet_UDP_Send: %s\n", SDLNet_GetError());

						timeOfPing = time(NULL);
						waitingForPong = SDL_TRUE;
					}
				} break;
			}
			continue;
		}

		// NOTE: does the server have packets waiting?
		if(SDLNet_SocketReady(serverFD)) {
			// NOTE: setup a packet which is big enough to store any client message
			UDPpacket packet;

			// NOTE: allocate space for packet
			packet.maxlen = 0xAA; // 170 bytes
			packet.data = (uint8_t *)malloc(0xAA);

			// NOTE: get the packet
			int recv = SDLNet_UDP_Recv(serverFD, &packet);
			if(!recv) {
				free(packet.data);
				continue;
			}

			// NOTE: read the flag for packet identity
			uint8_t flag = 0;
			uint32_t offset = 0;

			memcpy(&flag, packet.data, 1);
			offset += 1;

			// NOTE: process the packet
			switch(flag) {
				case 0x01: {

					net_login(plManager, &packet, &offset);

				} break;
				case 0x02: {
					
					net_logout(plManager, &packet, &offset);

				} break;
				case 0x07: {
					
					net_moveUp(plManager, &packet, &offset);

				} break;
				case 0x08: {
					
					net_moveDown(plManager, &packet, &offset);

				} break;
				case 0x09: {
					
					net_moveLeft(plManager, &packet, &offset);

				} break;
				case 0x0A: {
					
					net_moveRight(plManager, &packet, &offset);

				} break;
				case 0x0B: {

					net_sendOutPlInfo(plManager, &packet, &offset);
					
				} break;
				case 0x0C: {
					// NOTE: get the player which is logged in on the incoming address
					DB_Player *pl = pl_getDBInfo(plManager, packet.address);
					if(pl == NULL) break;

					// NOTE: need to make sure the pong is from the right player
					int ind = pl_getIndex(plManager, pl);

					// NOTE: player responding with a pong packet
					if(ind==playerToPing) {
						playerToPing++;
						waitingForPong = SDL_FALSE;
					}
				} break;
				case 0x0D: {
					
					net_sendOutNodeInfo(plManager, &packet, &offset);

				} break;
			}

			// NOTE: free the packet when done processing
			free(packet.data);
		}
	}

	// NOTE: free the player manager
	freePlayerManager(plManager);

	// NOTE: free socketset
	SDLNet_FreeSocketSet(socketSet);

	// NOTE: close the socket file descriptor
	SDLNet_UDP_Close(serverFD);

	libQuit();

	return 0;
}