[56] | 1 | /* |
---|
| 2 | * Abuse - dark 2D side-scrolling platform game |
---|
| 3 | * Copyright (c) 1995 Crack dot Com |
---|
[494] | 4 | * Copyright (c) 2005-2011 Sam Hocevar <sam@hocevar.net> |
---|
[56] | 5 | * |
---|
| 6 | * This software was released into the Public Domain. As with most public |
---|
[555] | 7 | * domain software, no warranty is made or implied by Crack dot Com, by |
---|
| 8 | * Jonathan Clark, or by Sam Hocevar. |
---|
[56] | 9 | */ |
---|
[2] | 10 | |
---|
[555] | 11 | #if defined HAVE_CONFIG_H |
---|
| 12 | # include "config.h" |
---|
| 13 | #endif |
---|
[56] | 14 | |
---|
[651] | 15 | #if HAVE_NETWORK |
---|
| 16 | |
---|
[2] | 17 | #include <stdio.h> |
---|
| 18 | #include <stdlib.h> |
---|
| 19 | #include <fcntl.h> |
---|
| 20 | #include <unistd.h> |
---|
| 21 | #include <sys/ioctl.h> |
---|
| 22 | #include <sys/stat.h> |
---|
| 23 | #include <sys/types.h> |
---|
| 24 | #include <sys/time.h> |
---|
| 25 | #include <string.h> |
---|
| 26 | #include <signal.h> |
---|
| 27 | #include <sys/socket.h> |
---|
| 28 | #include <netinet/in.h> |
---|
| 29 | #include <sys/types.h> |
---|
| 30 | #include <sys/ipc.h> |
---|
| 31 | #include <sys/shm.h> |
---|
| 32 | #include <bstring.h> |
---|
| 33 | #include <netdb.h> |
---|
| 34 | |
---|
[481] | 35 | #include "fileman.h" |
---|
| 36 | #include "netdrv.h" |
---|
| 37 | #include "gserver.h" |
---|
| 38 | #include "gclient.h" |
---|
| 39 | #include "undrv.h" |
---|
| 40 | #include "tcpip.h" |
---|
[56] | 41 | |
---|
[17] | 42 | #define real2shm(type,ptr) (ptr==NULL ? NULL : ((type *)((uint8_t *)(ptr)-(uint8_t *)base))) |
---|
| 43 | #define shm2real(type,ptr) (ptr==NULL ? NULL : ((type *)((intptr_t)(ptr)+(intptr_t)(base)))) |
---|
[2] | 44 | |
---|
| 45 | net_driver *driver=NULL; |
---|
| 46 | |
---|
| 47 | #ifdef __sgi |
---|
| 48 | #define next_process() sginap(0) |
---|
| 49 | #else |
---|
| 50 | #define next_process() usleep(10) |
---|
| 51 | #endif |
---|
| 52 | |
---|
| 53 | |
---|
| 54 | #ifdef __sgi |
---|
| 55 | void die(...) |
---|
| 56 | #else |
---|
| 57 | void die(int why) |
---|
| 58 | #endif |
---|
[124] | 59 | { |
---|
[2] | 60 | fprintf(stderr,"dieing\n"); |
---|
| 61 | if (driver) { delete driver; driver=NULL; } |
---|
| 62 | exit(0); |
---|
| 63 | } |
---|
| 64 | |
---|
| 65 | |
---|
| 66 | void mdie(char *reason) |
---|
| 67 | { |
---|
| 68 | fprintf(stderr,"net driver : %s\n",reason); |
---|
| 69 | if (driver) { driver->cleanup(); } |
---|
| 70 | exit(0); |
---|
| 71 | } |
---|
| 72 | |
---|
| 73 | void comm_failed() // general communication failure with engine |
---|
| 74 | { |
---|
[112] | 75 | fprintf(stderr,"net driver : Error occurred while trying to communicate with the engine\n"); |
---|
[2] | 76 | if (driver) { delete driver; driver=NULL; } |
---|
| 77 | exit(0); |
---|
| 78 | } |
---|
| 79 | |
---|
| 80 | int net_driver::add_joiner(int client_id, char *name) |
---|
| 81 | { |
---|
| 82 | join_array[client_id].next=base->join_list; |
---|
| 83 | base->join_list=real2shm(join_struct,&join_array[client_id]); |
---|
| 84 | join_array[client_id].client_id=client_id; |
---|
| 85 | strcpy(join_array[client_id].name,name); |
---|
| 86 | } |
---|
| 87 | |
---|
| 88 | |
---|
| 89 | void net_driver::cleanup() |
---|
| 90 | { |
---|
| 91 | base->input_state=INPUT_NET_DEAD; |
---|
| 92 | fprintf(stderr,"net driver : cleaning up\n"); |
---|
| 93 | if (shm_seg_id!=-1) |
---|
| 94 | shmctl(shm_seg_id,IPC_RMID,NULL); |
---|
[124] | 95 | if (shm_addr!=(void *)-1) |
---|
[2] | 96 | { |
---|
| 97 | shmdt((char *)shm_addr); |
---|
| 98 | shm_addr=(void *)-1; |
---|
| 99 | } |
---|
| 100 | |
---|
| 101 | undrv_cleanup(); |
---|
| 102 | unlink(DLOCK_NAME); |
---|
| 103 | } |
---|
| 104 | |
---|
| 105 | net_driver::~net_driver() |
---|
| 106 | { |
---|
| 107 | cleanup(); |
---|
| 108 | } |
---|
| 109 | |
---|
| 110 | int net_driver::setup_shm() |
---|
| 111 | { |
---|
| 112 | shm_addr=(void *)-1; // shmat returns -1 on failure |
---|
| 113 | shm_seg_id=-1; |
---|
| 114 | |
---|
| 115 | driver=this; |
---|
[494] | 116 | int catch_sigs[]={ SIGHUP,SIGINT,SIGQUIT,SIGILL,SIGABRT, |
---|
[124] | 117 | SIGIOT,SIGFPE,SIGKILL,SIGUSR1,SIGSEGV, |
---|
| 118 | SIGUSR2,SIGPIPE,SIGTERM,SIGCHLD, |
---|
| 119 | SIGCONT,SIGSTOP,SIGTSTP,SIGTTIN,SIGTTOU,-1}; |
---|
[2] | 120 | |
---|
| 121 | int i; |
---|
[494] | 122 | for (i=0; catch_sigs[i]!=-1; i++) // catch all signals in case we get |
---|
[2] | 123 | signal(catch_sigs[i],die); // interrupted before we remove shmid |
---|
| 124 | |
---|
| 125 | |
---|
| 126 | int alloc_size=sizeof(join_struct)*MAX_JOINERS+sizeof(base_memory_struct); |
---|
| 127 | |
---|
| 128 | shm_seg_id=shmget(IPC_PRIVATE,alloc_size,IPC_CREAT | 0777); |
---|
| 129 | |
---|
| 130 | |
---|
| 131 | if (shm_seg_id==-1) mdie("Unable to allocate shared memory"); |
---|
| 132 | |
---|
| 133 | |
---|
| 134 | shm_addr=shmat(shm_seg_id,NULL,0); // attach as read/write |
---|
[124] | 135 | if (shm_addr==(void *)-1) |
---|
[2] | 136 | mdie("could not attach shm seg"); |
---|
| 137 | |
---|
| 138 | base=(base_memory_struct *)shm_addr; |
---|
| 139 | |
---|
| 140 | base->join_list=real2shm(join_struct,NULL); |
---|
| 141 | base->mem_lock=0; |
---|
| 142 | base->calc_crcs=0; |
---|
| 143 | base->get_lsf=0; |
---|
| 144 | base->wait_reload=0; |
---|
| 145 | base->need_reload=0; |
---|
| 146 | base->input_state=INPUT_COLLECTING; |
---|
| 147 | base->current_tick=0; |
---|
| 148 | base->packet.packet_reset(); |
---|
| 149 | join_array=(join_struct *) (base+1); |
---|
| 150 | |
---|
| 151 | // see if we can attach this memory with the abuse engine |
---|
| 152 | if (out->write(&shm_seg_id,sizeof(shm_seg_id))!=sizeof(shm_seg_id)) |
---|
| 153 | comm_failed(); |
---|
| 154 | |
---|
| 155 | // wait for engine to ack it has attached |
---|
[17] | 156 | uint8_t ack=0; |
---|
[2] | 157 | if (in->read(&ack,1)!=1 || ack!=1) |
---|
| 158 | comm_failed(); |
---|
| 159 | |
---|
[124] | 160 | |
---|
[2] | 161 | if (shmctl(shm_seg_id,IPC_RMID,NULL)) // remove the shm id |
---|
| 162 | mdie("could not remove shm id"); |
---|
| 163 | |
---|
| 164 | shm_seg_id=-1; // mark id as not allocated |
---|
| 165 | return 1; |
---|
| 166 | |
---|
| 167 | } |
---|
| 168 | |
---|
| 169 | int net_driver::connect_to_engine(int argc, char **argv) |
---|
| 170 | { |
---|
| 171 | if (mkfifo(DIN_NAME,S_IRWXU | S_IRWXG | S_IRWXO)) |
---|
| 172 | { perror("Net driver : unable to make fifo in /tmp"); |
---|
| 173 | return 0; |
---|
| 174 | } |
---|
| 175 | chmod(DIN_NAME,S_IRWXU | S_IRWXG | S_IRWXO); // just to be sure umask doesn't screw us |
---|
| 176 | |
---|
| 177 | if (mkfifo(DOUT_NAME,S_IRWXU | S_IRWXG | S_IRWXO)) |
---|
| 178 | { perror("Net driver : unable to make fifo in /tmp"); |
---|
| 179 | return 0; |
---|
| 180 | } |
---|
| 181 | chmod(DOUT_NAME,S_IRWXU | S_IRWXG | S_IRWXO); |
---|
| 182 | |
---|
| 183 | int driver_out_fd=open(DOUT_NAME,O_RDWR); // open the pipe |
---|
| 184 | if (driver_out_fd<0) |
---|
[124] | 185 | { perror(DOUT_NAME); |
---|
[2] | 186 | exit(1); |
---|
| 187 | } |
---|
| 188 | |
---|
| 189 | int driver_in_fd=open(DIN_NAME,O_RDWR); |
---|
| 190 | if (driver_in_fd<0) |
---|
[124] | 191 | { |
---|
[2] | 192 | close(driver_out_fd); |
---|
[124] | 193 | perror(DIN_NAME); |
---|
[2] | 194 | exit(1); |
---|
| 195 | } |
---|
| 196 | |
---|
| 197 | in=new unix_fd(driver_in_fd); |
---|
| 198 | in->read_selectable(); |
---|
| 199 | out=new unix_fd(driver_out_fd); |
---|
[124] | 200 | |
---|
| 201 | if (in->read(®,sizeof(reg))!=sizeof(reg)) |
---|
[2] | 202 | mdie("unable to registration from engine"); |
---|
| 203 | } |
---|
| 204 | |
---|
[124] | 205 | net_driver::net_driver(int argc, char **argv, int comm_port, int game_port, net_protocol *proto) : |
---|
[2] | 206 | comm_port(comm_port), game_port(game_port), proto(proto) |
---|
| 207 | { |
---|
| 208 | debug=0; |
---|
| 209 | lsf_wait_list=NULL; |
---|
| 210 | crc_wait_list=NULL; |
---|
| 211 | |
---|
| 212 | base=NULL; |
---|
| 213 | in=out=NULL; |
---|
| 214 | game_face=new game_handler(); |
---|
| 215 | |
---|
| 216 | connect_to_engine(argc,argv); |
---|
| 217 | setup_shm(); |
---|
| 218 | int i; |
---|
[494] | 219 | for (i=1; i<argc; i++) if (!strcmp(argv[i],"-debug")) debug=1; |
---|
[2] | 220 | } |
---|
| 221 | |
---|
| 222 | int net_driver::become_server() |
---|
| 223 | { |
---|
| 224 | delete game_face; |
---|
| 225 | game_face=new game_server; |
---|
| 226 | return 1; |
---|
| 227 | } |
---|
| 228 | |
---|
| 229 | int net_driver::check_commands() |
---|
| 230 | { |
---|
| 231 | int ret=0; |
---|
| 232 | if (in->ready_to_read()) // commands from engine? |
---|
| 233 | { |
---|
[17] | 234 | uint8_t cmd; |
---|
[2] | 235 | if (in->read(&cmd,1)!=1) return 0; |
---|
| 236 | |
---|
| 237 | if (debug) |
---|
| 238 | { |
---|
| 239 | if (cmd<=EGCMD_DIE) |
---|
| 240 | { |
---|
[494] | 241 | char *cmds[]={ "open","close","read","write","seek","size","tell","setfs","crc_calced","process_lsf","request_lfs", |
---|
[124] | 242 | "equest_entry","become_server","block","reload_start","reload_end","send_input","input_missing", |
---|
| 243 | "kill_slackers","die"}; |
---|
| 244 | fprintf(stderr,"engine cmd : %s\n",cmds[cmd]); |
---|
[2] | 245 | } |
---|
| 246 | } |
---|
| 247 | |
---|
| 248 | switch (cmd) |
---|
| 249 | { |
---|
| 250 | case EGCMD_DIE : |
---|
| 251 | { |
---|
[124] | 252 | cmd=game_face->quit(); |
---|
| 253 | if (!out->write(&cmd,1)) { mdie("could not write block ack1"); } // send something to unblock engine |
---|
| 254 | mdie("received die command"); |
---|
[2] | 255 | } break; |
---|
| 256 | |
---|
| 257 | case NFCMD_RELOAD_START : |
---|
[124] | 258 | { |
---|
| 259 | cmd=game_face->start_reload(); |
---|
[494] | 260 | if (!out->write(&cmd,1)) { mdie("could not write start reload ack"); } // send something to unblock engine |
---|
[2] | 261 | } break; |
---|
| 262 | |
---|
| 263 | case NFCMD_RELOAD_END : |
---|
[124] | 264 | { |
---|
| 265 | cmd=game_face->end_reload(); |
---|
[494] | 266 | if (!out->write(&cmd,1)) { mdie("could not write end reload ack"); } // send something to unblock engine |
---|
[2] | 267 | } break; |
---|
| 268 | |
---|
| 269 | case NFCMD_BLOCK : |
---|
[124] | 270 | { |
---|
| 271 | if (!out->write(&cmd,1)) { mdie("could not write block ack1"); } // send something to unblock engine |
---|
| 272 | if (!in->read(&cmd,1)) { mdie("could not read block ack1"); } // send something to block ourself |
---|
[2] | 273 | } break; |
---|
| 274 | |
---|
| 275 | case NFCMD_INPUT_MISSING : // try to fetch the input via a loss-less net protocol |
---|
| 276 | { |
---|
[124] | 277 | game_face->input_missing(); |
---|
| 278 | if (out->write(&cmd,1)!=1) { mdie("could not write block ack1"); } // send something to unblock engine |
---|
[2] | 279 | } break; |
---|
[494] | 280 | |
---|
[2] | 281 | case NFCMD_KILL_SLACKERS : |
---|
| 282 | { |
---|
[124] | 283 | if (!game_face->kill_slackers()) |
---|
| 284 | { |
---|
| 285 | delete game_face; |
---|
| 286 | game_face=new game_handler(); |
---|
| 287 | } |
---|
| 288 | if (out->write(&cmd,1)!=1) { mdie("could not write block ack1"); } // send something to unblock engine |
---|
[2] | 289 | } break; |
---|
| 290 | case NFCMD_SEND_INPUT : |
---|
| 291 | { |
---|
[124] | 292 | game_face->add_engine_input(); |
---|
| 293 | if (out->write(&cmd,1)!=1) { mdie("could not write send ack1"); } // send something to unblock engine |
---|
| 294 | if (in->read(&cmd,1)!=1) { mdie("could not read send ack2"); } // read something to block ourselves for engine |
---|
[2] | 295 | } break; |
---|
| 296 | |
---|
| 297 | case NFCMD_REQUEST_ENTRY : |
---|
| 298 | { |
---|
[124] | 299 | uint8_t len; |
---|
| 300 | char name[256]; |
---|
| 301 | if (in->read(&len,1)!=1) { mdie("could not read server name length"); } |
---|
| 302 | if (in->read(name,len)!=len) { mdie("could not read server name"); } |
---|
| 303 | uint16_t success=join_server(name); |
---|
| 304 | if (out->write(&success,2)!=2) mdie("cound not send lsf read failure"); |
---|
[2] | 305 | } break; |
---|
[494] | 306 | |
---|
[2] | 307 | case NFCMD_BECOME_SERVER : |
---|
| 308 | { |
---|
[494] | 309 | cmd=become_server(); |
---|
[124] | 310 | if (out->write(&cmd,1)!=1) mdie("cound not send ok"); |
---|
[2] | 311 | } break; |
---|
[494] | 312 | |
---|
[2] | 313 | case NFCMD_REQUEST_LSF : |
---|
| 314 | { |
---|
[124] | 315 | uint8_t len; |
---|
| 316 | char name[256]; |
---|
| 317 | if (in->read(&len,1)!=1) { mdie("could not read lsf name length"); } |
---|
| 318 | if (in->read(name,len)!=len) { mdie("could not read lsf name"); } |
---|
| 319 | if (!get_lsf(name)) |
---|
| 320 | { |
---|
| 321 | len=0; |
---|
| 322 | if (out->write(&len,1)!=1) mdie("cound not send lsf read failure"); |
---|
| 323 | } else |
---|
| 324 | { |
---|
| 325 | len=strlen(name)+1; |
---|
| 326 | if (out->write(&len,1)!=1) mdie("cound not send lsf name len"); |
---|
| 327 | if (out->write(name,len)!=len) mdie("cound not send lsf name"); |
---|
| 328 | } |
---|
[2] | 329 | } break; |
---|
| 330 | |
---|
| 331 | case NFCMD_PROCESS_LSF : |
---|
| 332 | { |
---|
[124] | 333 | uint8_t len,name[256]; |
---|
| 334 | if (in->read(&len,1)!=1) { mdie("could not read lsf name length"); } |
---|
| 335 | if (in->read(name,len)!=len) { mdie("could not read lsf name"); } |
---|
[2] | 336 | |
---|
[124] | 337 | while (lsf_wait_list) |
---|
| 338 | { |
---|
| 339 | lsf_waiter *c=lsf_wait_list; |
---|
| 340 | lsf_wait_list=lsf_wait_list->next; |
---|
| 341 | uint8_t status=1; |
---|
| 342 | c->sock->write(&len,1); |
---|
| 343 | c->sock->write(name,len); |
---|
| 344 | delete c; |
---|
| 345 | } |
---|
[2] | 346 | } break; |
---|
| 347 | |
---|
[124] | 348 | case NFCMD_CRCS_CALCED : |
---|
[2] | 349 | { |
---|
[124] | 350 | while (crc_wait_list) |
---|
| 351 | { |
---|
| 352 | crc_waiter *c=crc_wait_list; |
---|
| 353 | crc_wait_list=crc_wait_list->next; |
---|
| 354 | uint8_t status=1; |
---|
| 355 | c->sock->write(&status,1); |
---|
| 356 | delete c; |
---|
| 357 | } |
---|
[2] | 358 | } break; |
---|
| 359 | |
---|
| 360 | case NFCMD_SET_FS : |
---|
| 361 | { |
---|
[124] | 362 | uint8_t size; |
---|
| 363 | char sn[256]; |
---|
| 364 | if (in->read(&size,1)!=1) mdie("could not read filename length"); |
---|
| 365 | if (in->read(sn,size)!=size) mdie("could not read server name"); |
---|
| 366 | fman->set_default_fs_name(sn); |
---|
[2] | 367 | |
---|
[124] | 368 | size=fetch_crcs(sn); // return success |
---|
| 369 | if (out->write(&size,1)!=1) mdie("could not send ok to engine"); |
---|
| 370 | } break; |
---|
[2] | 371 | |
---|
| 372 | case NFCMD_OPEN : |
---|
| 373 | { |
---|
[124] | 374 | uint8_t size[2]; |
---|
| 375 | char filename[300],mode[20],*fn; |
---|
| 376 | fn=filename; |
---|
| 377 | if (in->read(size,2)!=2 || |
---|
| 378 | in->read(filename,size[0])!=size[0] || |
---|
| 379 | in->read(mode,size[1])!=size[1]) |
---|
| 380 | mdie("incomplete open command from engine"); |
---|
[494] | 381 | |
---|
[124] | 382 | int fd=fman->rf_open_file(fn,mode); |
---|
| 383 | if (fd==-2) |
---|
| 384 | { |
---|
| 385 | uint8_t st[2]; |
---|
| 386 | st[0]=NF_OPEN_LOCAL_FILE; |
---|
| 387 | st[1]=strlen(fn)+1; |
---|
| 388 | if (out->write(st,2)!=2) comm_failed(); |
---|
| 389 | if (out->write(fn,st[1])!=st[1]) comm_failed(); |
---|
| 390 | } else if (fd==-1) |
---|
| 391 | { |
---|
| 392 | uint8_t st=NF_OPEN_FAILED; |
---|
| 393 | if (out->write(&st,1)!=1) comm_failed(); |
---|
| 394 | } else |
---|
| 395 | { |
---|
| 396 | uint8_t st=NF_OPEN_REMOTE_FILE; |
---|
[494] | 397 | if (out->write(&st,1)!=1) comm_failed(); |
---|
| 398 | if (out->write(&fd,sizeof(fd))!=sizeof(fd)) comm_failed(); |
---|
[124] | 399 | } |
---|
[2] | 400 | } break; |
---|
| 401 | case NFCMD_CLOSE : |
---|
| 402 | case NFCMD_SIZE : |
---|
| 403 | case NFCMD_TELL : |
---|
| 404 | case NFCMD_SEEK : |
---|
| 405 | case NFCMD_READ : |
---|
| 406 | { |
---|
[124] | 407 | int fd; |
---|
| 408 | if (in->read(&fd,sizeof(fd))!=sizeof(fd)) comm_failed(); |
---|
[2] | 409 | |
---|
[124] | 410 | switch (cmd) |
---|
| 411 | { |
---|
| 412 | case NFCMD_CLOSE : |
---|
| 413 | { |
---|
| 414 | fman->rf_close(fd); |
---|
| 415 | uint8_t st=1; |
---|
[494] | 416 | if (out->write(&st,1)!=1) comm_failed(); |
---|
[124] | 417 | } break; |
---|
| 418 | case NFCMD_SIZE : |
---|
| 419 | { |
---|
| 420 | int32_t x=fman->rf_file_size(fd); |
---|
[494] | 421 | if (out->write(&x,sizeof(x))!=sizeof(x)) comm_failed(); |
---|
[124] | 422 | } break; |
---|
| 423 | case NFCMD_TELL : |
---|
| 424 | { |
---|
| 425 | int32_t offset=fman->rf_tell(fd); |
---|
| 426 | if (out->write(&offset,sizeof(offset))!=sizeof(offset)) comm_failed(); |
---|
| 427 | } break; |
---|
| 428 | case NFCMD_SEEK : |
---|
| 429 | { |
---|
| 430 | int32_t offset; |
---|
| 431 | if (in->read(&offset,sizeof(offset))!=sizeof(offset)) comm_failed(); |
---|
| 432 | offset=fman->rf_seek(fd,offset); |
---|
| 433 | if (out->write(&offset,sizeof(offset))!=sizeof(offset)) comm_failed(); |
---|
| 434 | } break; |
---|
| 435 | case NFCMD_READ : |
---|
| 436 | { |
---|
| 437 | int32_t size; |
---|
| 438 | if (in->read(&size,sizeof(size))!=sizeof(size)) comm_failed(); |
---|
| 439 | fman->rf_read(fd,out,size); |
---|
| 440 | } break; |
---|
| 441 | } |
---|
| 442 | } break; |
---|
[2] | 443 | default : |
---|
| 444 | { fprintf(stderr,"net driver : unknown net command %d\n",cmd); die(0); } |
---|
[124] | 445 | } |
---|
[2] | 446 | ret=1; |
---|
| 447 | } |
---|
| 448 | |
---|
| 449 | ret|=game_face->process_net(); |
---|
| 450 | return ret; |
---|
| 451 | } |
---|
| 452 | |
---|
| 453 | |
---|
| 454 | int net_driver::join_server(char *server_name) // ask remote server for entry into game |
---|
| 455 | { |
---|
| 456 | char sn_start[256]; |
---|
| 457 | strcpy(sn_start,server_name); |
---|
| 458 | |
---|
[151] | 459 | net_socket *sock=connect_to_server(server_name, DEFAULT_COMM_PORT, 0); |
---|
[2] | 460 | if (!sock) |
---|
[124] | 461 | { |
---|
[2] | 462 | fprintf(stderr,"unable to connect\n"); |
---|
| 463 | return 0; |
---|
| 464 | } |
---|
| 465 | |
---|
[17] | 466 | uint8_t ctype=CLIENT_ABUSE; |
---|
| 467 | uint16_t port=lstl(game_port),cnum; |
---|
[2] | 468 | |
---|
[17] | 469 | uint8_t reg; |
---|
[2] | 470 | if (sock->write(&ctype,1)!=1 || // send server out game port |
---|
| 471 | sock->read(®,1)!=1) // is remote engine registered? |
---|
| 472 | { delete sock; return 0; } |
---|
| 473 | |
---|
| 474 | |
---|
| 475 | // maker sure the two games are both registered or unregistered or sync problems |
---|
| 476 | // will occur. |
---|
| 477 | |
---|
[61] | 478 | if (!reg) |
---|
[2] | 479 | { |
---|
| 480 | fprintf(stderr, |
---|
[124] | 481 | "This server is not running the registered version of abuse, and\n" |
---|
| 482 | "you are (thanks!). So that there are no conflict between the two games\n" |
---|
| 483 | "please start with the -share option when connecting to this server\n" |
---|
| 484 | "example : abuse -net somewhere.someplace.net -share\n"); |
---|
[2] | 485 | delete sock; |
---|
| 486 | return 0; |
---|
| 487 | } |
---|
| 488 | |
---|
| 489 | char uname[256]; |
---|
| 490 | if (getlogin()) |
---|
| 491 | strcpy(uname,getlogin()); |
---|
| 492 | else strcpy(uname,"unknown"); |
---|
[17] | 493 | uint8_t len=strlen(uname)+1; |
---|
[2] | 494 | |
---|
| 495 | if (sock->write(&len,1)!=1 || |
---|
[124] | 496 | sock->write(uname,len)!=len || |
---|
[2] | 497 | sock->write(&port,2)!=2 || // send server out game port |
---|
| 498 | sock->read(&port,2)!=2 || // read server's game port |
---|
| 499 | sock->read(&cnum,2)!=2 || cnum==0 // read player number (cannot be 0 because 0 is server) |
---|
| 500 | ) |
---|
| 501 | { delete sock; return 0; } |
---|
| 502 | |
---|
| 503 | port=lstl(port); |
---|
| 504 | cnum=lstl(cnum); |
---|
| 505 | |
---|
| 506 | server_name=sn_start; |
---|
| 507 | net_socket *data_sock=connect_to_server(server_name,port,1,net_socket::SOCKET_FAST); |
---|
| 508 | if (!data_sock) { delete sock; return 0; } |
---|
| 509 | |
---|
| 510 | delete game_face; |
---|
| 511 | game_face=new game_client(sn_start,sock,data_sock); |
---|
| 512 | return cnum; |
---|
| 513 | } |
---|
| 514 | |
---|
| 515 | |
---|
[124] | 516 | net_socket *net_driver::connect_to_server(char *&name, int port, int force_port, |
---|
| 517 | net_socket::socket_type sock_type) |
---|
[2] | 518 | { |
---|
| 519 | char *oname=name; |
---|
| 520 | net_address *addr=proto->get_node_address(name, port, force_port); |
---|
[124] | 521 | if (!addr) |
---|
[2] | 522 | { |
---|
| 523 | if (debug) fprintf(stderr,"No IP address for name %s\n",oname); |
---|
| 524 | return NULL; |
---|
| 525 | } |
---|
| 526 | |
---|
| 527 | if (debug) |
---|
| 528 | fprintf(stderr,"connecting to server %s\n",oname); |
---|
| 529 | net_socket *sock=proto->connect_to_server(addr,sock_type); |
---|
| 530 | delete addr; |
---|
| 531 | return sock; |
---|
| 532 | } |
---|
| 533 | |
---|
| 534 | |
---|
| 535 | int net_driver::get_lsf(char *name) // contact remot host and ask for lisp startup file filename |
---|
| 536 | { |
---|
| 537 | char *name_start=name; |
---|
| 538 | net_socket *sock=connect_to_server(name); |
---|
| 539 | if (!sock) return 0; |
---|
| 540 | |
---|
[17] | 541 | uint8_t ctype=CLIENT_LSF_WAITER; |
---|
| 542 | uint8_t len; |
---|
[2] | 543 | |
---|
| 544 | if (sock->write(&ctype,1)!=1 || |
---|
| 545 | sock->read(&len,1)!=1 || len==0 || |
---|
| 546 | sock->read(name_start,len)!=len) |
---|
| 547 | { |
---|
[124] | 548 | delete sock; |
---|
[2] | 549 | return 0; |
---|
[124] | 550 | } |
---|
[2] | 551 | |
---|
| 552 | delete sock; |
---|
[124] | 553 | return 1; |
---|
[2] | 554 | } |
---|
| 555 | |
---|
| 556 | |
---|
| 557 | |
---|
| 558 | int net_driver::fetch_crcs(char *server) |
---|
| 559 | { |
---|
| 560 | net_socket *sock=connect_to_server(server); |
---|
| 561 | if (!sock) return 0; |
---|
[17] | 562 | uint8_t cmd=CLIENT_CRC_WAITER; |
---|
[2] | 563 | if (sock->write(&cmd,1)!=1 || |
---|
[124] | 564 | sock->read(&cmd,1)!=1) |
---|
[2] | 565 | { delete sock; return 0; } |
---|
| 566 | delete sock; |
---|
[124] | 567 | return cmd; |
---|
[2] | 568 | } |
---|
| 569 | |
---|
| 570 | |
---|
| 571 | int net_driver::add_client(int type, net_socket *sock, net_address *from) |
---|
| 572 | { |
---|
| 573 | switch (type) |
---|
| 574 | { |
---|
| 575 | case CLIENT_CRC_WAITER : |
---|
| 576 | { |
---|
| 577 | if (debug) |
---|
| 578 | fprintf(stderr,"add crc waiter\n"); |
---|
| 579 | |
---|
| 580 | crc_wait_list=new crc_waiter(sock,crc_wait_list); |
---|
[124] | 581 | base->calc_crcs=1; |
---|
[2] | 582 | return 1; |
---|
| 583 | } break; |
---|
| 584 | case CLIENT_LSF_WAITER : |
---|
| 585 | { |
---|
| 586 | if (debug) |
---|
| 587 | fprintf(stderr,"add lsf waiter\n"); |
---|
| 588 | lsf_wait_list=new lsf_waiter(sock,lsf_wait_list); |
---|
| 589 | base->get_lsf=1; |
---|
| 590 | return 1; |
---|
| 591 | } break; |
---|
| 592 | default : |
---|
| 593 | { |
---|
| 594 | int ret=game_face->add_client(type,sock,from); |
---|
| 595 | if (!ret && debug) |
---|
| 596 | fprintf(stderr,"unknown client type %d\n",type); |
---|
| 597 | return ret; |
---|
| 598 | } |
---|
[124] | 599 | |
---|
| 600 | } |
---|
[2] | 601 | return 0; |
---|
| 602 | } |
---|
[651] | 603 | |
---|
| 604 | #endif // HAVE_NETWORK |
---|
| 605 | |
---|