00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035 #include <config.h>
00036
00037 #include <errno.h>
00038 #include <stdio.h>
00039 #include <sys/types.h>
00040 #include <sys/socket.h>
00041 #include <netinet/in.h>
00042 #include <arpa/inet.h>
00043 #include <netdb.h>
00044 #include <unistd.h>
00045
00046 #include "empio.h"
00047 #include "empthread.h"
00048 #include "file.h"
00049 #include "misc.h"
00050 #include "optlist.h"
00051 #include "player.h"
00052 #include "power.h"
00053 #include "proto.h"
00054 #include "prototypes.h"
00055
00056 static struct emp_qelem Players;
00057 static int player_socket;
00058 static size_t player_addrlen;
00059
00060 void
00061 player_init(void)
00062 {
00063 emp_initque(&Players);
00064 init_player_commands();
00065
00066 player_socket = tcp_listen(*listen_addr ? listen_addr : NULL,
00067 loginport, &player_addrlen);
00068 }
00069
00070 struct player *
00071 player_new(int s)
00072 {
00073 struct player *lp;
00074
00075 lp = malloc(sizeof(struct player));
00076 if (!lp)
00077 return NULL;
00078 memset(lp, 0, sizeof(struct player));
00079 if (s >= 0) {
00080
00081 lp->iop = io_open(s, IO_READ | IO_WRITE | IO_NBLOCK, IO_BUFSIZE);
00082 if (!lp->iop) {
00083 free(lp);
00084 return NULL;
00085 }
00086 emp_insque(&lp->queue, &Players);
00087 lp->cnum = 255;
00088 lp->curid = -1;
00089 time(&lp->curup);
00090 }
00091 return lp;
00092 }
00093
00094 struct player *
00095 player_delete(struct player *lp)
00096 {
00097 struct player *back;
00098
00099 back = (struct player *)lp->queue.q_back;
00100 if (back)
00101 emp_remque(&lp->queue);
00102 if (lp->iop) {
00103
00104 io_close(lp->iop);
00105 lp->iop = 0;
00106 }
00107 free(lp);
00108
00109 return back;
00110 }
00111
00112 struct player *
00113 player_next(struct player *lp)
00114 {
00115 if (lp == 0)
00116 lp = (struct player *)Players.q_forw;
00117 else
00118 lp = (struct player *)lp->queue.q_forw;
00119 if (&lp->queue == &Players)
00120 return 0;
00121 return lp;
00122 }
00123
00124 struct player *
00125 player_prev(struct player *lp)
00126 {
00127 if (lp == 0)
00128 lp = (struct player *)Players.q_back;
00129 else
00130 lp = (struct player *)lp->queue.q_back;
00131 if (&lp->queue == &Players)
00132 return 0;
00133 return lp;
00134 }
00135
00136
00137
00138
00139 struct player *
00140 getplayer(natid cnum)
00141 {
00142 struct emp_qelem *qp;
00143 struct player *pl;
00144
00145 for (qp = Players.q_forw; qp != &Players; qp = qp->q_forw) {
00146 pl = (struct player *)qp;
00147 if (pl->cnum == cnum && pl->state == PS_PLAYING)
00148 return pl;
00149 }
00150
00151 return NULL;
00152 }
00153
00154
00155 void
00156 player_accept(void *unused)
00157 {
00158 struct sockaddr *sap;
00159 void *inaddr;
00160 int s = player_socket;
00161 struct player *np;
00162 socklen_t len;
00163 int ns;
00164 int set = 1;
00165 int stacksize;
00166 char buf[128];
00167 #ifdef RESOLVE_IPADDRESS
00168 struct hostent *hostp;
00169 #endif
00170
00171
00172 sap = malloc(player_addrlen);
00173
00174 while (1) {
00175 empth_select(s, EMPTH_FD_READ);
00176 len = player_addrlen;
00177 ns = accept(s, sap, &len);
00178
00179 if (ns < 0) {
00180 logerror("new socket accept");
00181 continue;
00182 }
00183
00184 (void)setsockopt(ns, SOL_SOCKET, SO_KEEPALIVE, &set, sizeof(set));
00185 np = player_new(ns);
00186 if (!np) {
00187 logerror("can't create player for fd %d", ns);
00188 close(ns);
00189 continue;
00190 }
00191 #ifdef HAVE_GETADDRINFO
00192 inaddr = sap->sa_family == AF_INET
00193 ? (void *)&((struct sockaddr_in *)sap)->sin_addr
00194 : (void *)&((struct sockaddr_in6 *)sap)->sin6_addr;
00195
00196 if (!inet_ntop(sap->sa_family, inaddr,
00197 np->hostaddr, sizeof(np->hostaddr))) {
00198 logerror("inet_ntop() failed: %s", strerror(errno));
00199 close(ns);
00200 continue;
00201 }
00202 #else
00203 inaddr = &((struct sockaddr_in *)sap)->sin_addr;
00204 strcpy(np->hostaddr, inet_ntoa(*(struct in_addr *)inaddr));
00205 #endif
00206 #ifdef RESOLVE_IPADDRESS
00207 hostp = gethostbyaddr(inaddr, player_addrlen, sap->sa_family);
00208 if (NULL != hostp)
00209 strcpy(np->hostname, hostp->h_name);
00210 #endif
00211
00212 stacksize = 100000
00213 + MAX(WORLD_SZ() * sizeof(int) * 7,
00214 MAXNOC * sizeof(struct powstr));
00215 sprintf(buf, "Player (fd #%d)", ns);
00216 empth_create(player_login, stacksize, 0, buf, np);
00217 }
00218 }