#include "Flatline.h" #include "Flatline_Client.h" #include "Mariusnet_Public.h" //#include "PortForwardWrapper.h" int client_slot = 0; RGBA green = {0, 0xFF, 0, 0}; RGBA red = {0, 0, 0xFF, 0}; RGBA grey = {0x80,0x80,0x80,0x80}; int FLcEventHandler( int eventIndex, int args[] ) { switch(eventIndex) { case(EV_DISCONNECT): FLrPlayerDisconnect( args[0] ); break; case(EV_KILLED): ONrCharacter_SetHitPoints( PlayerList[args[0]]->Chr, 0); case(EV_DOOR_OPEN): OBJrDoor_ForceOpen( args[0] ); break; case(EV_CONSOLE_USE): OBJrConsole_OnActivate( OBJrConsole_GetByID(args[0]), PlayerList[args[1]]->Chr ); break; case(EV_RESPAWN): ONrCorpse_Create(PlayerList[args[0]]->Chr); break; default: break; } return 0; } void FLcConnect( int ip, short port ) { if( NetPlatform_Initalize()) { static flatline_packet packet; memset(&client_address, 0, sizeof(sockaddr_in)); sock = NetUDPSocket_Create(ntohs(port), &client_address); address.sin_family = AF_INET; address.sin_port = port; address.sin_addr.S_un.S_addr = ip; //address.sin_family = AF_INET; address.sin_port = htons(27777); address.sin_addr.S_un.S_addr = inet_addr("192.168.0.1"); packet.id = CONNECT_SEND; memcpy(((connect_send*)(packet.data))->country , "XD", 2); memcpy(((connect_send*)(packet.data))->name, player_name, 256); DDrConsole_PrintF("%s", ((connect_send*)(packet.data))->name); CreateThread(NULL, 0, StartClient, &packet, 0, 0); } } bool FLrClient_Run(flatline_packet* packet) { char data[1400]; uint16_t len; int j; int sent_bytes; /* PortMappingContainer_C PMC = { "", "27777", "27777", "UDP", "", "", "Flatline!" }; uPnP_Remove( &PMC );*/ client_connected = 0; //starts the connection DDrConsole_PrintF("Connecting to server %s on socket %i", inet_ntoa(address.sin_addr), client_sock); sent_bytes = NetUDPSocket_Send(client_sock, (sockaddr*)&address, (char*)packet, FLATLINE_HEADER + sizeof(connect_send) ); if(sent_bytes == SOCKET_ERROR) { NetCatchError(); } //loops once per second waiting for a reply. for(j = 0; j < CONNECTION_TIMEOUT; j++) { while(NetUDPSocket_Recieve(client_sock, (sockaddr_storage *) &client_address, data, &len)){ packet = (flatline_packet*)data; if(packet->id == CONNECT_REPLY) { if(packet->connect_reply.goodtogo){ client_connected = 1; client_slot = ((connect_reply*)packet->data)->player_slot; PlayerList[client_slot] = Players+client_slot; PlayerList[client_slot]->Chr = ONgGameState->PlayerCharacter; DDrConsole_PrintColored("Connection successful!",0,green, grey); /*THIS MIGHT BE BAD*/ snprintf( PlayerList[client_slot]->name, 32, "%s", player_name ); //disable local input. DDrPatch_NOOP(0x004FA929, 5 + 6 + 5); //Disable local turning //DDrPatch_NOOP(0x004F7EA8, 2); //DDrPatch_Byte( 0x004F7EB1 , 0xE9); //DDrPatch_MakeJump( 0x004F7EB1, 0x004F8030 ); //DDrPatch_Byte(0x04ED6FB, 0xEB); //DDrConsole_PrintF("Slot %i", ((connect_reply*)packet)->player_slot); //DDrPatch_NOOP(0x43B23,0x10); //DDrPatch_NOOP(0x4EC248,(0x5A-0x48)); //DDrPatch_NOOP(0x4EC861, 6); //Close Mariusnet collection because it hurts latency MSNet_RoomExit(); break; } else { DDrConsole_PrintF("Connection rejected: %s", ((connect_reply*)packet->data)->message); return false; break; } } } if(client_connected) break; DDrConsole_PrintF("Connection timing out in %i seconds...", CONNECTION_TIMEOUT - j); Sleep(1000); } //the client timed out without recieving an error message. if(!client_connected) { DDrConsole_PrintColored("Connection timed out.",0,red, grey); return false; } return true; } void FLrClient_GetPackets() { flatline_packet packet; uint16_t len; //#define SPAM_INPUT #ifdef SPAM_INPUT struct timeval lasttime; struct timeval thistime; gettimeofday(&lasttime, 0); #endif while(NetUDPSocket_Recieve(client_sock, (sockaddr_storage *) &client_address, &packet, &len)) { //packet = (flatline_packet*)data; //DDrConsole_PrintF("Data recieved, length %i, type %i", len, ((flatline_packet*)data)->id); switch(packet.id) { case MESSAGE: COrMessage_Print(packet.data, "chat", 0); break; case CHANGE_NAME: if(PlayerList[(char)packet.data[0]]) { char message_buffer[1024]; sprintf(message_buffer,"%s changed their name to %s", PlayerList[(char)packet.data[0]]->name, packet.data + 1); COrMessage_Print(message_buffer, "name_change", 0); /*THIS MIGHT BE BAD*/ snprintf(PlayerList[packet.data[0]]->name, 32, "%s", packet.data + 1); } break; case CONNECT_SEND: ;if(1) { flatline_packet connect_recv; memcpy(&connect_recv.connect_reply.message,"This isn't a server!", sizeof("This isn't a server!")); NetUDPSocket_Send(client_sock, (sockaddr *) &address, (char*)&connect_recv, sizeof(bool) + FLATLINE_HEADER + sizeof("This isn't a server!")); } case CONNECT_REPLY: break; //extra packet or something. case NEW_PLAYER: ;if(1) { //haxhaxhax CharacterObject* Char = &(packet.new_player.Character); uint32_t chr_index = 0; Character* PC; DDrConsole_PrintF("%i | %i", packet.new_player.Playernumber ,client_slot); //Char->OSD.Options = 0; if(packet.new_player.Playernumber == client_slot) { PlayerList[packet.new_player.Playernumber] = &Players[0]; PC = (ONgGameState->PlayerCharacter); Players[0].Chr = PC; } else { ONrGameState_NewCharacter(Char, NULL, NULL, &chr_index); ONgGameState->CharacterStorage[chr_index].charType = 0; PlayerList[packet.new_player.Playernumber] = &Players[chr_index]; Players[chr_index].Chr = &(ONgGameState->CharacterStorage[chr_index]); Players[chr_index].Chr->Flags &= 0xFFBFFFFF; Players[chr_index].spawnnumber = chr_index; DDrConsole_PrintF("Spawning player %s, class %s, slot %i", ((new_player*)(packet.data))->Character.OSD.Name, ((new_player*)(packet.data))->Character.OSD.Class,chr_index) ; /*THIS MIGHT BE BAD*/ snprintf(Players[chr_index].name, 32, "%s", ((new_player*)(packet.data))->Character.OSD.Name); } //Players[((new_player*)(packet.data))->Playernumber].spawnnumber = ONrGameState_NewCharacter(&(((new_player*)(packet.data))->Character), NULL, NULL, 0); break; } case FLATLINE_EVENT: FLcEventHandler( packet.flatline_event.event_index, packet.flatline_event.intArray ); break; case PK_PING: packet.id = PK_PONG; NetUDPSocket_Send(client_sock, (sockaddr *) &address, (char*)&packet, FLATLINE_HEADER + 4); break; case PK_PLAYER_DATA: FLcReadPlayerData( &packet, len ); break; default: DDrConsole_PrintF("Warning, recieved badly formed packet!"); break; } } }