source: Daodan/src/Flatline.c @ 486

Last change on this file since 486 was 486, checked in by gumby, 13 years ago

Fixed(?) Code.

File size: 17.2 KB
Line 
1#include "Flatline.h"
2#include "Oni_Character.h"
3#include "Flatline_Server.h"
4#include <sys/time.h>
5#include <time.h>
6uint32_t last1 = 0; uint32_t last2 = 0;
7player_info Players[MAX_PLAYERS] = {{0}, {0}, {0}, {0}};
8player_info * PlayerList[MAX_CONNECTIONS] = {0};
9const char * Rejection_Messages[][255] = {
10        {"Server is full"},
11        {"-2"},
12        {"-3"},
13        {"-4"},
14        {"-5"},
15};
16
17bool FLrServer_PacketCallback(char* data, int datalen, int from)
18{
19        flatline_packet * packet = (flatline_packet*)data;
20        static int recieved = 0;
21        sockaddr_in sender;
22        sender.sin_family = AF_INET;
23        sender.sin_port = htons(27777);
24        sender.sin_addr = *((struct in_addr*)(int*)&from);
25       
26
27        //packet->data[datalen] = '\0';
28       
29        //DDrConsole_PrintF("Packet \r%d recieved from %i",  ++recieved, from);
30
31       
32       
33        //if data[0] != CONNECT_SEND, search in playerlist for ip address
34       
35        int i, j; //stupid C90, won't let me declare my counter inside a for loop.
36        bool found_player = 0;
37       
38        switch(packet->id) {
39                //rewrite this when we get TCP support.
40                //rewrite this before we get TCP support*
41                //the way of seeing if there is room for players sucks.
42                case CONNECT_SEND:
43                        ;
44                        flatline_packet connect_recv;
45                        connect_recv.id = CONNECT_REPLY;
46                        //if(Players[i].ip == sender.sin_addr.S_un.S_addr) break; //needs to send an error message
47                        DDrConsole_PrintF("%s connected from IP_ADDRESS", ((connect_send*)(packet->data))->name);
48                        sender.sin_addr.S_un.S_addr = htonl(sender.sin_addr.S_un.S_addr);
49                        player_info * playah = FLrServer_AddPlayer(from,((connect_send*)(packet->data))->name, 0);
50                        if(!((int)playah > -5 && (int)playah <= 0)) {
51                                ((connect_reply*)(connect_recv.data))->goodtogo = 1;
52                                ((connect_reply*)(connect_recv.data))->player_slot = playah->list_slot;
53                                DDrConsole_PrintF("Slot: %i", playah->list_slot);
54                                NetTCPServer_Send((sockaddr *) &sender, (char*)&connect_recv, sizeof(connect_reply) - 256 + FLATLINE_HEADER);
55                                Sleep(100); //remove when we implement TCP.
56                                flatline_packet new_char = {0};
57                                new_char.id = NEW_PLAYER;
58                                CharacterObject* Char = &(((new_player*)(new_char.data))->Character);
59                                memset(Char, 0, sizeof(CharacterObject));
60                                Char->Header.Type = 'CHAR';
61                                Char->OSD.Options = char_dontaim;
62                                for(j = 0; j < max_connections; j++) {
63                                        if(PlayerList[j] != 0) {
64                                                (*(new_player*)(void*)&new_char.data).Playernumber = j;
65                                                sprintf(Char->OSD.Name,"%s",PlayerList[j]->name);
66                                                sprintf(Char->OSD.Class, "%s", TMrInstance_GetInstanceName(PlayerList[j]->Chr->ONCC));
67                                                NetTCPServer_Send((sockaddr *) &sender, (char*)&new_char, sizeof(new_player) + FLATLINE_HEADER );
68                                        }
69
70                                }
71                        }
72                        else {
73                                //fix the error messages...
74                                DDrConsole_PrintF("Server is full. :(");
75                                ((connect_reply*)(connect_recv.data))->goodtogo = 0;
76                                sender.sin_addr.S_un.S_addr = htonl(sender.sin_addr.S_un.S_addr);
77                                memcpy(((connect_reply*)(connect_recv.data))->message,"Server is full.", sizeof("Server is full."));
78                                NetTCPServer_Send((sockaddr *) &sender, (char*)&connect_recv, sizeof(bool)*2 + FLATLINE_HEADER + sizeof("Server is full."));   
79
80                        } 
81
82
83                        break;
84                case CONNECT_REPLY:
85                        break;  //do nothing...a server shouldn't recieve this type of packet.
86                case MESSAGE:
87                        for(i = 0; i < MAX_PLAYERS; i++) {
88                                DDrConsole_PrintF("%i : %i | %s : %s", from, Players[i].ip, inet_ntoa(*(struct in_addr*)&from), inet_ntoa(*(struct in_addr*)&(Players[i].ip)));
89                                if(Players[i].ip == sender.sin_addr.S_un.S_addr) {
90                                        found_player = 1;
91                                        break;
92                                }       
93                        }
94                        if(found_player == 0) return true;
95
96                        data[datalen] = 0;
97                        char message_buffer[512] = {0};
98                        DDrConsole_PrintF("%s: %s", Players[i].name, packet->data);
99                        sprintf(message_buffer, "%s: %s", Players[i].name, packet->data);
100                        flatline_packet message;
101                        message.id = MESSAGE;
102                        int message_size = sprintf(message.data, "%s", message_buffer);
103                        COrMessage_Print(message_buffer, "chat", 0);
104                        UDPServer_SendToAll(&message, message_size + 1 + FLATLINE_HEADER);
105                        break;
106                case CHANGE_NAME:
107                        ; //wtf, needed or i get an error.
108                        DDrConsole_PrintF("Changing Name to: %s", packet->data);
109                        for(i = 0; i < MAX_PLAYERS; i++) {
110                                if(Players[i].ip == sender.sin_addr.S_un.S_addr) {
111                                        found_player = 1;
112                                        break;
113                                }       
114                        }
115                        if(found_player == 0) return true;
116                        bool name_exists = 0;
117                        for(j = 0; j < MAX_PLAYERS; j++) {
118                                if(!strcmp(packet->data, Players[j].name)) {
119                                        name_exists = 1;
120                                        break;
121                                }
122                        }
123                        if(!name_exists) {
124                                char message_buffer[1024];
125                                sprintf(message_buffer,"%s changed their name to %s", Players[i].name, packet->data);
126                                COrMessage_Print(message_buffer, "name_change", 0);
127                                memcpy(Players[i].name, packet->data, 256);
128
129                        }
130                        break;
131                case PLAYER_INPUT:
132                       
133                        for(i = 0; i < max_connections; i++) {
134                                if(PlayerList[i] != 0 && PlayerList[i]->ip == sender.sin_addr.S_un.S_addr) {
135                                        found_player = 1;
136                                        break;
137                                }       
138                        }
139                       
140                        if(found_player == 0) return true;
141
142                        input_struct * packet_input = (input_struct*)(packet->data);
143
144                       
145                        PlayerList[i]->Actions1 = packet_input->Actions1;
146                        PlayerList[i]->Actions2 = packet_input->Actions2;
147                        PlayerList[i]->MouseDeltaX = packet_input->MouseDeltaX;
148                        PlayerList[i]->MouseDeltaY = packet_input->MouseDeltaY;
149                       
150               
151                        break;
152                default:
153                        DDrConsole_PrintF("Warning, recieved badly formed packet!");
154                        break;
155        }
156        return true;
157}
158
159bool FLrServer_Run()
160{
161        // Get the local hostname
162        char szHostName[255];
163        gethostname(szHostName, 255);
164        struct hostent *host_entry;
165        host_entry=gethostbyname(szHostName);
166        DDrConsole_PrintF("Server started at %s...", inet_ntoa (*(struct in_addr *)*host_entry->h_addr_list));
167        return NetUDPServer_Listen(27777, FLrServer_PacketCallback);
168}
169
170        RGBA green = {0, 0xFF, 0, 0};
171        RGBA red = {0, 0, 0xFF, 0};
172        RGBA grey = {0x80,0x80,0x80,0x80};
173       
174//FLrClient_Run
175//Looping function that waits for packets from the server.
176//TODO: Convert connection packet stuff to TCP
177int client_slot = 0;
178bool FLrClient_Run(flatline_packet* packet)
179{
180        client_connected = 0;
181        char data[1400];
182        uint16_t len;
183        int j;
184       
185        //starts the connection
186        DDrConsole_PrintF("Connecting to server %s on socket %i",  inet_ntoa(address.sin_addr), client_sock);
187        int sent_bytes = NetUDPSocket_Send(client_sock, (sockaddr*)&address, (char*)packet, 255);
188        if(sent_bytes == SOCKET_ERROR) {
189                NetCatchError();
190        }
191        //loops once per second waiting for a reply.
192        for(j = 0; j < CONNECTION_TIMEOUT; j++) {
193                while(NetUDPSocket_Recieve(client_sock, (sockaddr_storage *) &client_address, data, &len)){             
194                        packet = (flatline_packet*)data;
195                        if(packet->id == CONNECT_REPLY) {
196                                if(((connect_reply*)packet->data)->goodtogo){
197                                        client_connected = 1;
198                                        client_slot = ((connect_reply*)packet->data)->player_slot;
199                                        DDrConsole_PrintColored("Connection successful!",0,green, grey);
200                                        //DDrConsole_PrintF("Slot %i",  ((connect_reply*)packet)->player_slot);
201                                        break;
202                                }
203                                else {
204                                        DDrConsole_PrintF("Connection rejected: %s", ((connect_reply*)packet->data)->message);
205                                        return false;
206                                        break;
207                                }
208                        }
209                }
210                if(client_connected) break;
211                DDrConsole_PrintF("Connection timing out in %i seconds...", CONNECTION_TIMEOUT - j);
212                Sleep(1000);
213        }
214        //the client timed out without recieving an error message.
215        if(!client_connected) {
216                DDrConsole_PrintColored("Connection timed out.",0,red, grey);
217                return false;
218        }
219#define SPAM_INPUT
220#ifdef SPAM_INPUT
221                struct timeval lasttime;
222                gettimeofday(&lasttime, 0);
223                struct timeval thistime;
224#endif
225                while(1) {
226#ifdef SPAM_INPUT
227                        gettimeofday(&thistime, 0);
228                       
229                        //DDrConsole_PrintF("%i.%i | %i.%i | %i.%i",lasttime.tv_sec, lasttime.tv_usec, thistime.tv_sec, thistime.tv_usec,
230                        //      thistime.tv_sec - lasttime.tv_sec, thistime.tv_usec - lasttime.tv_usec);
231                        //checks to see if enough time has passed since the last input update (by default once every 10ms)
232                        if( 
233                                ((thistime.tv_sec > lasttime.tv_sec) && ((thistime.tv_usec + 1000000 - lasttime.tv_usec ) > update_rate * 1000) )
234                                || ((thistime.tv_sec == lasttime.tv_sec) && ((thistime.tv_usec - lasttime.tv_usec ) > update_rate * 1000))
235                        ) {
236                               
237                                lasttime.tv_usec = ++thistime.tv_usec; //in case recieving packets takes less than 1 ms.
238                                flatline_packet input_packet;
239                                input_packet.id = PLAYER_INPUT;
240                               
241                                if( ((GameState*)(ONgGameState))->Input.Current.Actions1 != last1 || ((GameState*)(ONgGameState))->Input.Current.Actions2 != last2) {
242                                        last1 =((GameState*)(ONgGameState))->Input.Current.Actions1;
243                                        last2 =((GameState*)(ONgGameState))->Input.Current.Actions2;
244                                }
245
246                                ((input_struct*)(void*)(input_packet.data))->Actions1 = ((GameState*)(ONgGameState))->Input.Current.Actions1;
247                                ((input_struct*)(void*)(input_packet.data))->Actions2 = ((GameState*)(ONgGameState))->Input.Current.Actions2;
248                                ((input_struct*)(void*)(input_packet.data))->MouseDeltaX = ((GameState*)(ONgGameState))->Input.MouseDeltaX;
249                                ((input_struct*)(void*)(input_packet.data))->MouseDeltaY = ((GameState*)(ONgGameState))->Input.MouseDeltaY;
250                                sent_bytes = NetUDPSocket_Send(client_sock,(sockaddr *) &address, (char*)&input_packet, sizeof(input_struct) + FLATLINE_HEADER);                       
251                                //if(sent_bytes == SOCKET_ERROR)        NetCatchError();
252                        }
253#endif
254                        if(NetUDPSocket_Recieve(client_sock, (sockaddr_storage *) &client_address, data, &len)) {
255                                packet = (flatline_packet*)data;
256                                //DDrConsole_PrintF("Data recieved, length %i, type %i", len, ((flatline_packet*)data)->id);
257                                switch(packet->id) {
258                case MESSAGE:
259                        COrMessage_Print(packet->data, "chat", 0);
260                        break;
261                case CONNECT_SEND:
262                        ;
263                        flatline_packet connect_recv;
264                        memcpy(((connect_reply*)&(connect_recv.data))->message,"This isn't a server!", sizeof("This isn't a server!"));
265                        NetUDPSocket_Send(client_sock, (sockaddr *) &address, (char*)&connect_recv, sizeof(bool) + FLATLINE_HEADER + sizeof("This isn't a server!"));                   
266                case CONNECT_REPLY:
267                        break; //extra packet or something.
268                case NEW_PLAYER:
269                        ;
270                        uint32_t chr_index;
271                        DDrConsole_PrintF("%i |  %i", ((new_player*)(packet->data))->Playernumber ,client_slot);
272                       
273                        if(((new_player*)(packet->data))->Playernumber == client_slot) {
274                                PlayerList[((new_player*)(packet->data))->Playernumber] = Players;
275                                Character* PC = (Character*)(((GameState*)ONgGameState)->PlayerCharacter);
276                                Players[0].Chr = PC;
277
278                        }
279                        else {
280                                ONrGameState_NewCharacter(&(((new_player*)(packet->data))->Character), NULL, NULL, &chr_index);
281                                PlayerList[((new_player*)(packet->data))->Playernumber] = &Players[chr_index];
282                                Players[chr_index].Chr = &(((GameState*)ONgGameState)->CharacterStorage[chr_index]);
283                                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) ;
284                        }
285                        //Players[((new_player*)(packet->data))->Playernumber].spawnnumber = ONrGameState_NewCharacter(&(((new_player*)(packet->data))->Character), NULL, NULL, 0);
286                        break;
287                case PLAYER_DATA:;
288                        player_data * data = (void*)packet->data;
289                        uint16_t i = data->PlayerNum;
290                        //DDrConsole_PrintF("Got data for Player %i, %x", i, PlayerList[i]);
291                        if (i > max_connections || PlayerList[i] == 0) break;
292                       
293                        //PlayerList[i]->Chr = ((GameState *)ONgGameState)->CharacterStorage;
294                       
295                        PlayerList[i]->Chr->Health = data->Health;
296                        PlayerList[i]->Chr->MaxHealth = data->MaxHealth;
297                        PlayerList[i]->Chr->Position = data->Position;
298                        PlayerList[i]->Chr->Location = data->Location;
299                        PlayerList[i]->Chr->LastPosition = data->LastPosition;
300                        PlayerList[i]->Chr->Facing = data->Facing;
301                        PlayerList[i]->Chr->DesiredFacing = data->DesiredFacing;
302                        PlayerList[i]->Chr->CosmeticFacing = data->CosmeticFacing;
303                        PlayerList[i]->Actions1 = data->Inputs.Actions1;
304                        PlayerList[i]->Actions2 = data->Inputs.Actions2;
305                        ActiveCharacter * Active = ((ActiveCharacter*)(ONrGetActiveCharacter(PlayerList[i]->Chr)));
306                        if(!Active) break;
307                       
308                        Active->PhyContext_->Position = data->Position;
309                       
310                        /*
311                        int ptr = 0;
312                        (TMrInstance_GetDataPtr('TRAM',data->Animation,&ptr)); *(void**)((char*)Active + 0x1AF8) = ptr;
313                                               
314                        *(uint16_t *)((char*)Active + 0x1AFC) = data->AnimationToState;
315                        *(uint16_t *)((char*)Active + 0x1AFE) = data->AnimationFromState;
316                        *(uint16_t *)((char*)Active + 0x1B00) = data->AnimationType;
317                        *(uint16_t *)((char*)Active + 0x1B02) = data->NextAnimationType;
318                        *(uint16_t *)((char*)Active + 0x1B04) = data->AnimationType2;
319                        */
320                        if((int)*((char*)(Active + 0x1AF8) + 0x166) > data->Frame + 1)
321                        *(uint16_t *)((char*)Active + 0x1C88) = data->Frame + 1;
322                               
323                        break;
324                default:
325                        DDrConsole_PrintF("Warning, recieved badly formed packet!");
326                        break;
327                                }
328                        }
329                        else {
330                                Sleep(1);
331                        }
332                }
333
334        return true;
335}
336
337//UDPServer_SendToAll
338//Sends a packet to all the clients currently connected.
339//Returns the number of players sent to.
340int UDPServer_SendToAll(void* packet, int size) {
341        int j;
342        int players = 0;
343        sockaddr_in address;
344        memset(&address, 0, sizeof(sockaddr_in)); 
345        address.sin_family = AF_INET;
346        address.sin_addr.s_addr = htonl(INADDR_ANY);
347        address.sin_port = htons(27777);
348        for(j = 0; j < max_connections; j++) {
349                if (PlayerList[j] != 0 && PlayerList[j]->ip != inet_addr("127.0.0.1")) {
350                        address.sin_addr.s_addr = htonl(PlayerList[j]->ip);//*((struct in_addr*)(int*)&(Players[j].ip));               
351                        int sent_bytes = NetUDPServer_Send((sockaddr *) &address, (char*)packet, size);
352                        if(sent_bytes == SOCKET_ERROR) NetCatchError();
353                        else players++;
354                }
355        }
356        return players;
357}
358
359player_info *FLr_FindEmptySlot() {
360        int j;
361        for(j = 0; j < MAX_PLAYERS; j++) {
362                if (Players[j].ip == 0) {
363                        return &Players[j];
364                }
365        }
366        return 0;
367}
368
369extern uint16_t max_connections;
370uint16_t FLr_FindEmptyListSlot() {
371        int j;
372        for(j = 0; j < max_connections; j++) {
373                if (PlayerList[j] == 0) {
374                        return j;
375                }
376        }
377        return -1;
378}
379void * ONICALL FLrInput_Update_Keys(void) {
380#ifndef SPAM_INPUT
381        if(client_connected) {
382                flatline_packet input_packet;
383                input_packet.id = PLAYER_INPUT;
384                ((input_struct*)(void*)(input_packet.data))->Actions1 = ((GameState*)(ONgGameState))->Input.Current.Actions1;
385                ((input_struct*)(void*)(input_packet.data))->Actions2 = ((GameState*)(ONgGameState))->Input.Current.Actions2;
386                ((input_struct*)(void*)(input_packet.data))->MouseDeltaX = ((GameState*)(ONgGameState))->Input.MouseDeltaX;
387                ((input_struct*)(void*)(input_packet.data))->MouseDeltaY = ((GameState*)(ONgGameState))->Input.MouseDeltaY;
388                int sent_bytes = NetUDPSocket_Send(client_sock,(sockaddr *) &address, (char*)&input_packet, sizeof(input_struct) + FLATLINE_HEADER);
389                return ONgGameState;
390        }
391#endif
392        if(!(server_started || client_connected)) return ONgGameState;
393        uint16_t i;
394        for(i = 0; i < max_connections; i++) {
395                if(PlayerList[i] == 0) continue;
396                char * Active_Player = (void*)ONrGetActiveCharacter(PlayerList[i]->Chr);
397               
398                if(Active_Player == 0) continue;
399                GameInput * Active_Input = (void*)( Active_Player + 0x2158);
400                if(server_started) {
401                        flatline_packet data_out = {0};
402                        data_out.id = PLAYER_DATA;
403                        player_data * data = (void*)&(data_out.data);
404                        data->PlayerNum = i;
405                        data->Health = PlayerList[i]->Chr->Health;
406                        data->MaxHealth = PlayerList[i]->Chr->MaxHealth;
407                        data->Position = PlayerList[i]->Chr->Position;
408                        data->Location = PlayerList[i]->Chr->Location;
409                        data->LastPosition = PlayerList[i]->Chr->LastPosition;
410                        data->Facing = PlayerList[i]->Chr->Facing;
411                        data->DesiredFacing = PlayerList[i]->Chr->DesiredFacing;
412                        data->CosmeticFacing = PlayerList[i]->Chr->CosmeticFacing;
413                        data->Frame = *(Active_Player + 0x1C88);
414                        memcpy(data->Animation, TMrInstance_GetInstanceName(*(void **)(Active_Player + 0x1AF8)), 32);
415                        data->AnimationToState = *(uint16_t *)(Active_Player + 0x1AFC);
416                        data->AnimationFromState = *(uint16_t *)(Active_Player + 0x1AFE);
417                        data->AnimationType = *(uint16_t *)(Active_Player + 0x1B00);
418                        data->NextAnimationType = *(uint16_t *)(Active_Player + 0x1B02);
419                        data->AnimationType2= *(uint16_t *)(Active_Player + 0x1B04);
420                        if(i == 0) {
421                                data->Inputs.Actions1 = ((GameState*)(ONgGameState))->Input.Current.Actions1;
422                                data->Inputs.Actions2 = ((GameState*)(ONgGameState))->Input.Current.Actions2;
423                        }
424                        else{
425                                data->Inputs.Actions1 = PlayerList[i]->Actions1;
426                                data->Inputs.Actions2 = PlayerList[i]->Actions2;
427                        }
428                        UDPServer_SendToAll(&data_out, sizeof(player_data) + FLATLINE_HEADER);
429                }
430               
431                if( (server_started && i !=0) || (!server_started && i != client_slot)) {
432                        Active_Input->Stop.Actions1 = ~PlayerList[i]->Actions1 & Active_Input->Current.Actions1;
433                        Active_Input->Stop.Actions2 = ~PlayerList[i]->Actions2 & Active_Input->Current.Actions2;
434                        Active_Input->Start.Actions1 = ~Active_Input->Current.Actions1 & PlayerList[i]->Actions1;
435                        Active_Input->Start.Actions2 = ~Active_Input->Current.Actions2 & PlayerList[i]->Actions2;
436                        Active_Input->Current.Actions1 = PlayerList[i]->Actions1;
437                        Active_Input->Current.Actions2 = PlayerList[i]->Actions2;
438                        Active_Input->Stopped.Actions1 = ~Active_Input->Current.Actions1;
439                        Active_Input->Stopped.Actions2 = ~Active_Input->Current.Actions2;
440                        Active_Input->MouseDeltaX = PlayerList[i]->MouseDeltaX;
441                        Active_Input->MouseDeltaY = PlayerList[i]->MouseDeltaY;
442                }
443        }
444        return ONgGameState;
445}
Note: See TracBrowser for help on using the repository browser.