source: Daodan/src/flatline/Flatline_Server.c@ 976

Last change on this file since 976 was 877, checked in by alloc, 11 years ago

Daodan: Moved flatline to subfolder, flatline enabled through patch "flatline"

File size: 13.0 KB
Line 
1#include "Flatline.h"
2#include "Flatline_Server.h"
3#include <windows.h>
4//#include "PortForwardWrapper.h"
5#include "Mariusnet_Public.h"
6//I hereby apologize for the uglyness of the below code.
7//It was never intended to be "final" code, much less shared with anyone
8
9int total_players = 0;
10uint16_t max_connections = MAX_CONNECTIONS;
11
12player_info* FLrServer_AddPlayer(int ip, char* name, bool is_server, bool is_bot) {
13 flatline_packet new_char = {0};
14 CharacterObject* Char;
15 uint32_t player_slot = 0;
16 int playerlist_slot = 0;
17
18 if(is_server || total_players < max_connections) {
19
20 int i = 0;
21 int k = 0;
22
23 //Skip for the host
24 if(!is_server)
25 {
26 char* zero = strchr(name, 0);
27 playerlist_slot = FLr_FindEmptyListSlot();
28
29 total_players++;
30
31 //checks to see if a name exists or not
32 //then appends [#] on the end of it if it does
33 //May be buggy, come back to this.
34 if(zero - name > 28) zero = name + 28;
35 for(i = 0; i < max_connections; i++) {
36 if(PlayerList[i] != 0 && !strcmp(name, PlayerList[i]->name)) {
37 k++;
38 sprintf(zero, "[%i]", k);
39 i = 0;
40 }
41 }
42 }
43
44 new_char.new_player.Playernumber = playerlist_slot;
45
46 //Set up a new Character structure to be spawned as the new player.
47 //Can this code be surrounded with if(!is_server){}?
48 Char = &new_char.new_player.Character;
49 memset(Char, 0, sizeof(CharacterObject));
50 Char->Header.Type = 'CHAR';
51 sprintf(Char->OSD.Name,"%s",name);
52 sprintf(Char->OSD.Class, "%s", "konoko_generic");
53 if(is_bot) {
54 Char->OSD.MeleeID = 22;
55 Char->OSD.JobID = 1;
56 Char->OSD.MinimalAlertLevel = 4;
57 Char->OSD.InvestigatingAlertLevel = 4;
58 Char->OSD.InitialAlertLevel = 4;
59 Char->OSD.StartJobAlertLevel = 4;
60 }
61 else if( !is_server )
62 {
63 Char->Header.Position.X = PlayerList[0]->Chr->Position.X;
64 Char->Header.Position.Y = PlayerList[0]->Chr->Position.Y;
65 Char->Header.Position.Z = PlayerList[0]->Chr->Position.Z;
66 }
67
68 //TMrInstance_GetDataPtr('ONCC', "striker_easy_1", PlayerList[playerlist_slot]->Chr->ONCC);
69
70 new_char.id = NEW_PLAYER;
71 if(!is_server) {
72 ONrGameState_NewCharacter(Char, NULL, NULL, &(player_slot));
73 //move this to a set up characters function...
74 if(!is_bot) ONgGameState->CharacterStorage[player_slot].charType = 0;
75
76 PlayerList[playerlist_slot] = Players+player_slot;
77 PlayerList[playerlist_slot]->spawnnumber = player_slot;
78 PlayerList[playerlist_slot]->Chr = &(ONgGameState->CharacterStorage)[player_slot];
79 //PlayerList[playerlist_slot]->Chr->Flags = chr_dontaim | chr_unkillable; //&= 0xFFBFFFFF; //WTF
80 if(!is_bot) PlayerList[playerlist_slot]->Chr->Flags &= 0xFFBFFFFF; //WTF, magic number.
81 /*THIS MIGHT BE BAD*/ snprintf(PlayerList[playerlist_slot]->Chr->Name, 32, "%s", name);
82 /*THIS MIGHT BE BAD*/ snprintf(PlayerList[playerlist_slot]->name, 32, "%s", name);
83 UDPServer_SendToAll( (char*)&new_char, sizeof(new_player) + FLATLINE_HEADER );
84
85 }
86 else {
87 PlayerList[0] = Players;
88 PlayerList[0]->Chr = (Character *)(((GameState * )(ONgGameState))->CharacterStorage);
89 }
90
91 //add player to list
92
93 PlayerList[playerlist_slot]->ip = ip;
94 PlayerList[playerlist_slot]->list_slot = playerlist_slot;
95 /*THIS MIGHT BE BAD*/ snprintf(PlayerList[playerlist_slot]->name, 32, "%s", name);
96
97 MultiplayerStatus.PleaseUpdateAllPlayers = 1;
98
99 return &Players[player_slot];
100 }
101 return (player_info*)(-1);
102}
103
104void FLrServer_Initialize(){
105 FLrServer_AddPlayer(inet_addr("127.0.0.1"), "host", 1, 0);
106}
107
108//UDPServer_SendToAll
109//Sends a packet to all the clients currently connected.
110//Returns the number of players sent to.
111int UDPServer_SendToAll(void* packet, int size) {
112 int j;
113 int players = 0;
114 sockaddr_in address;
115 memset(&address, 0, sizeof(sockaddr_in));
116 address.sin_family = AF_INET;
117 address.sin_addr.s_addr = htonl(INADDR_ANY);
118 address.sin_port = htons(FLATLINE_PORT);
119 for(j = 0; j < max_connections; j++) {
120 if (PlayerList[j] != 0 && PlayerList[j]->ip && (PlayerList[j]->ip != inet_addr("127.0.0.1"))) {
121 int sent_bytes;
122 address.sin_addr.s_addr = htonl(PlayerList[j]->ip);//*((struct in_addr*)(int*)&(Players[j].ip));
123 DDrConsole_PrintF("Sending packet to %i", PlayerList[j]->ip);
124 sent_bytes = NetUDPServer_Send((sockaddr *) &address, (char*)packet, size);
125 if(sent_bytes == SOCKET_ERROR) NetCatchError();
126 else players++;
127 }
128 }
129 return players;
130}
131
132//FLsPublic_Event
133//Sends an event (door opening, player disconnecting, etc) to all players
134//Always make sure you send a pointer to this, even if it is just one arg. ;).
135//If it is void the double door in State crashes. Probably stack corruption,
136//I'm not sure exactly why.
137//So we return 0 to stop that.
138int FLsPublic_Event( const unsigned int eventIndex, const int * args )
139{
140 int numArgs = FLrEvent_GetNumArgs( eventIndex );
141 int ret;
142 flatline_packet eventPacket = {0};
143 eventPacket.id = FLATLINE_EVENT;
144 eventPacket.flatline_event.event_index = eventIndex;
145 ret = memcpy( eventPacket.flatline_event.intArray, args, sizeof(int) * numArgs );
146 ret = UDPServer_SendToAll( &eventPacket, sizeof(int) * (numArgs + 1) + FLATLINE_HEADER );
147 return 0;
148}
149
150void FLsPingAll()
151{
152 flatline_packet ping;
153 ping.id = PK_PING;
154 lastPingTime = ping.ping = GetTickCount();
155 UDPServer_SendToAll(&ping, FLATLINE_HEADER + 4);
156}
157
158void FLsUpdateName( int index, char* name )
159{
160 flatline_packet message;
161 int message_size;
162
163 char message_buffer[1024];
164 sprintf(message_buffer,"%s changed their name to %s", PlayerList[index]->name, name);
165 COrMessage_Print(message_buffer, "name_change", 0);
166
167 /*THIS MIGHT BE BAD*/ snprintf(PlayerList[index]->name, 32, "%s", name);
168 /*THIS MIGHT BE BAD*/ snprintf(PlayerList[index]->Chr->Name, 32, "%s", name);
169
170 message.id = CHANGE_NAME;
171 message.data[0] = index;
172 message_size = sprintf(message.data + 1, "%s", name);
173
174 UDPServer_SendToAll(&message, message_size + 2 + FLATLINE_HEADER);
175}
176void FLsSend_BINACHAR( short j, sockaddr* socket )
177{
178
179 ActiveCharacter* AC = ONrGetActiveCharacter( PlayerList[j]->Chr);
180 flatline_packet new_char = {0};
181 CharacterObject* Char = &new_char.new_player.Character;
182
183 new_char.id = NEW_PLAYER;
184 new_char.new_player.Playernumber = j;
185
186// memset(Char, 0, sizeof(CharacterObject));
187 Char->Header.Type = 'CHAR';
188 Char->OSD.Options = chr_dontaim;
189
190 sprintf(Char->OSD.Name,"%s",PlayerList[j]->name);
191
192 sprintf(Char->OSD.Class, "%s", TMrInstance_GetInstanceName(PlayerList[j]->Chr->ONCC));
193
194 if(AC && AC->PhyContext)
195 {
196 Char->Header.Position = AC->PhyContext->Position;
197 }
198 else
199 {
200 Char->Header.Position.X = 0;
201 Char->Header.Position.Y = 0;
202 Char->Header.Position.Z = 0;
203 }
204
205 NetTCPServer_Send(socket, (char*)&new_char, sizeof(new_player) + FLATLINE_HEADER );
206}
207bool FLrServer_PacketCallback(char* data, int datalen, int from)
208{
209 int i, j;
210 bool found_player = 0;
211 flatline_packet * packet = (flatline_packet*)data;
212 static int recieved = 0;
213 sockaddr_in sender;
214 sender.sin_family = AF_INET;
215 sender.sin_port = htons(FLATLINE_PORT);
216 sender.sin_addr = *((struct in_addr*)(int*)&from);
217
218
219 //packet->data[datalen] = '\0';
220
221 //DDrConsole_PrintF("Packet \r%d recieved from %i", ++recieved, from);
222
223
224
225 //if data[0] != CONNECT_SEND, search in playerlist for ip address
226
227
228
229
230 switch(packet->id) {
231 flatline_packet connect_recv;
232 player_info * playah;
233 //rewrite this when we get TCP support.
234 //rewrite this before we get TCP support*
235 //the way of seeing if there is room for players sucks.
236 case CONNECT_SEND:
237 ;
238
239 connect_recv.id = CONNECT_REPLY;
240
241 //if(Players[i].ip == sender.sin_addr.S_un.S_addr) break; //needs to send an error message
242 sender.sin_addr.S_un.S_addr = htonl(sender.sin_addr.S_un.S_addr);
243 playah = FLrServer_AddPlayer(from,packet->connect_send.name, 0, 0);
244 DDrConsole_PrintF("%s connected from %s", packet->connect_send.name, inet_ntoa(sender.sin_addr ) );
245 if(!((int)playah > -5 && (int)playah <= 0)) {
246
247 connect_recv.connect_reply.goodtogo = 1;
248 connect_recv.connect_reply.player_slot = playah->list_slot;
249 //DDrConsole_PrintF("Slot: %i", playah->list_slot);
250
251 //sending this several times to make sure it gets through. Really need to make up some form of packet tracking.
252 NetUDPServer_Send((sockaddr *) &sender, (char*)&connect_recv, sizeof(connect_reply) + FLATLINE_HEADER);
253 NetUDPServer_Send((sockaddr *) &sender, (char*)&connect_recv, sizeof(connect_reply) + FLATLINE_HEADER);
254 NetUDPServer_Send((sockaddr *) &sender, (char*)&connect_recv, sizeof(connect_reply) + FLATLINE_HEADER);
255 NetUDPServer_Send((sockaddr *) &sender, (char*)&connect_recv, sizeof(connect_reply) + FLATLINE_HEADER);
256 NetUDPServer_Send((sockaddr *) &sender, (char*)&connect_recv, sizeof(connect_reply) + FLATLINE_HEADER);
257 Sleep(100);
258
259
260
261 for(j = 0; j < max_connections; j++) {
262 if(PlayerList[j] != 0) {
263 FLsSend_BINACHAR( j, (sockaddr *)&sender);
264 }
265
266 }
267 }
268 else {
269 //fix the error messages...
270 DDrConsole_PrintF("Server is full. :(");
271 connect_recv.connect_reply.goodtogo = 0;
272 sender.sin_addr.S_un.S_addr = htonl(sender.sin_addr.S_un.S_addr);
273 memcpy(&connect_recv.connect_reply.message,"Server is full.", sizeof("Server is full."));
274 NetTCPServer_Send((sockaddr *) &sender, (char*)&connect_recv, sizeof(bool)*2 + FLATLINE_HEADER + sizeof("Server is full."));
275
276 }
277
278
279 break;
280 case CONNECT_REPLY:
281 break; //do nothing...a server shouldn't recieve this type of packet.
282 case MESSAGE:
283 for(i = 0; i < MAX_PLAYERS; i++) {
284 //DDrConsole_PrintF("%i : %i | %s : %s", from, Players[i].ip, inet_ntoa(*(struct in_addr*)&from), inet_ntoa(*(struct in_addr*)&(Players[i].ip)));
285 if(Players[i].ip == sender.sin_addr.S_un.S_addr) {
286 found_player = 1;
287 break;
288 }
289 }
290 if(found_player == 0) break;
291 else {
292 char message_buffer[512] = {0};
293 flatline_packet message;
294 int message_size;
295 data[datalen] = 0;
296
297 DDrConsole_PrintF("%s: %s", Players[i].name, packet->data);
298 sprintf(message_buffer, "%s: %s", Players[i].name, packet->data);
299
300 message.id = MESSAGE;
301 message_size = sprintf(message.data, "%s", message_buffer);
302 COrMessage_Print(message_buffer, "chat", 0);
303 UDPServer_SendToAll(&message, message_size + 1 + FLATLINE_HEADER);
304 break;
305 }
306 case CHANGE_NAME:
307 for(i = 0; i < MAX_PLAYERS; i++) {
308 if(PlayerList[i] && PlayerList[i]->ip == sender.sin_addr.S_un.S_addr) {
309 found_player = 1;
310 break;
311 }
312 }
313 if(found_player == 0) break;
314 else {
315 bool name_exists = 0;
316 for(j = 0; j < MAX_PLAYERS; j++) {
317 if(PlayerList[j] && !strcmp(packet->data, PlayerList[j]->name)) {
318 name_exists = 1;
319 break;
320 }
321 }
322 if(!name_exists) {
323 FLsUpdateName( i, packet->data );
324 }
325 break;
326 }
327 case PLAYER_INPUT:
328
329 for(i = 0; i < max_connections; i++) {
330 if(PlayerList[i] != 0 && PlayerList[i]->ip == sender.sin_addr.S_un.S_addr) {
331 found_player = 1;
332 break;
333 }
334 }
335
336 if(found_player == 0) break;
337 else {
338 input_struct * packet_input = &packet->input_struct;
339
340
341 PlayerList[i]->InputFromClient.Actions1 = packet_input->Actions1;
342 PlayerList[i]->InputFromClient.Actions2 = packet_input->Actions2;
343 PlayerList[i]->InputFromClient.MouseDeltaX = packet_input->MouseDeltaX;
344 PlayerList[i]->InputFromClient.MouseDeltaY = packet_input->MouseDeltaY;
345 PlayerList[i]->FacingFromClient = packet_input->DesiredFacing;
346 //PlayerList[i]->LastInputTime = packet_input->Time;
347
348 break;
349 }
350 case PK_PONG:
351 for(i = 0; i < max_connections; i++) {
352 if(PlayerList[i] != 0 && PlayerList[i]->ip == sender.sin_addr.S_un.S_addr) {
353 found_player = 1;
354 break;
355 }
356 }
357
358 if(found_player == 0) break;
359 if(packet->ping != lastPingTime)
360 {
361 PlayerList[i]->Ping = 999;
362 }
363 else
364 {
365 PlayerList[i]->Ping = GetTickCount() - packet->ping;
366 }
367 break;
368 case PK_MISSING_PLAYER:
369 if(packet->integer < MAX_PLAYERS)
370 {
371 FLsSend_BINACHAR( packet->integer, &sender);
372 }
373 break;
374 default:
375 DDrConsole_PrintF("Warning, recieved badly formed packet!");
376 break;
377 }
378 return true;
379}
380
381
382
383bool FLrServer_Run()
384{
385 m_announcegame Game;
386 HRESULT ret;
387/* PortMappingContainer_C PMC =
388 {
389 "",
390 "27777",
391 "27777",
392 "UDP",
393 "",
394 "",
395 "Flatline!"
396 };*/
397 // Get the local hostname
398 char szHostName[255];
399 struct hostent *host_entry;
400 gethostname(szHostName, 255);
401
402 host_entry=gethostbyname(szHostName);
403
404 /*strcpy( PMC.InternalClient, inet_ntoa (*(struct in_addr *)*host_entry->h_addr_list) );
405 ret = uPnP_Forward( &PMC );
406 if(!ret)
407 {
408 DDrConsole_Print( "Port Forwarded" );
409 }
410 else
411 {
412 LPSTR Message;
413 FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_SYSTEM, &ret,0,0,&Message,0,NULL);
414 DDrConsole_Print( Message );
415 }
416*/
417 DDrConsole_PrintF("Server started at %s...", inet_ntoa (*(struct in_addr *)*host_entry->h_addr_list));
418
419 Game.port = htons(FLATLINE_PORT);
420 /*THIS MIGHT BE BAD*/ snprintf(Game.g.Buffer, 128, "%s's Game", MariusLogin);
421
422 MSNet_CreateGame( &Game );
423
424 return NetUDPServer_Listen(27777, FLrServer_PacketCallback);
425}
Note: See TracBrowser for help on using the repository browser.