source: Daodan/MSVC/Flatline_Server.c@ 787

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

stuff

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