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 #include <config.h>
00035
00036 #include <errno.h>
00037 #include <stdio.h>
00038 #include "com.h"
00039 #include "empio.h"
00040 #include "empthread.h"
00041 #include "file.h"
00042 #include "journal.h"
00043 #include "misc.h"
00044 #include "nat.h"
00045 #include "optlist.h"
00046 #include "player.h"
00047 #include "proto.h"
00048 #include "prototypes.h"
00049 #include "tel.h"
00050
00051
00052 static int command(void);
00053 static int status(void);
00054
00055 struct player *player;
00056
00057 void
00058 player_main(struct player *p)
00059 {
00060 struct natstr *natp;
00061 int secs;
00062 char buf[128];
00063
00064 p->state = PS_PLAYING;
00065 player = p;
00066 time(&player->lasttime);
00067 time(&player->curup);
00068 show_motd();
00069 if (init_nats() < 0) {
00070 pr("Server confused, try again later\n");
00071 return;
00072 }
00073 natp = getnatp(player->cnum);
00074 if (!gamehours(player->curup)) {
00075 pr("Empire hours restriction in force\n");
00076 if (natp->nat_stat != STAT_GOD)
00077 return;
00078 }
00079 daychange(player->curup);
00080 if ((player->minleft = getminleft(player->curup, m_m_p_d)) <= 0) {
00081 pr("Time exceeded today\n");
00082 return;
00083 }
00084 if (natp->nat_stat != STAT_VIS
00085 && natp->nat_last_login
00086 && (strcmp(natp->nat_hostaddr, player->hostaddr)
00087 || strcmp(natp->nat_userid, player->userid))) {
00088 pr("Last connection from: %s", ctime(&natp->nat_last_login));
00089 pr(" to: %s",
00090 natp->nat_last_login <= natp->nat_last_logout
00091 ? ctime(&natp->nat_last_logout) : "?");
00092 pr(" by: %s@%s\n",
00093 natp->nat_userid,
00094 *natp->nat_hostname ? natp->nat_hostname : natp->nat_hostaddr);
00095 }
00096 strcpy(natp->nat_userid, player->userid);
00097 strcpy(natp->nat_hostname, player->hostname);
00098 strcpy(natp->nat_hostaddr, player->hostaddr);
00099
00100 time(&natp->nat_last_login);
00101 putnat(natp);
00102 journal_login();
00103 if (natp->nat_flags & NF_INFORM && natp->nat_tgms > 0) {
00104 if (natp->nat_tgms == 1)
00105 pr("You have a new telegram waiting ...\n");
00106 else
00107 pr("You have %s new telegrams waiting ...\n",
00108 numstr(buf, natp->nat_tgms));
00109 natp->nat_tgms = 0;
00110 }
00111
00112 while (status()) {
00113 if (command() == 0 && !player->aborted)
00114 break;
00115 player->aborted = 0;
00116 empth_yield();
00117 }
00118
00119 natp = getnatp(player->cnum);
00120
00121
00122
00123
00124 time(&natp->nat_last_logout);
00125 secs = MAX(natp->nat_last_logout - player->lasttime, 15);
00126 natp->nat_minused += secs / 60;
00127 secs = secs % 60;
00128 if (chance(secs / 60.0))
00129 natp->nat_minused += 1;
00130 putnat(natp);
00131 pr("Bye-bye\n");
00132 journal_logout();
00133 }
00134
00135 static int
00136 command(void)
00137 {
00138 char *redir;
00139 char scanspace[1024];
00140
00141 if (getcommand(player->combuf) < 0)
00142 return 0;
00143 if (parse(player->combuf, scanspace, player->argp, player->comtail,
00144 &player->condarg, &redir) < 0) {
00145 pr("See \"info Syntax\"?\n");
00146 } else {
00147 if (dispatch(player->combuf, redir) < 0)
00148 pr("Try \"list of commands\" or \"info\"\n");
00149 }
00150 return 1;
00151 }
00152
00153 static int
00154 status(void)
00155 {
00156 struct natstr *natp;
00157 int old_nstat, minute;
00158 char buf[128];
00159
00160 if (player->state == PS_SHUTDOWN)
00161 return 0;
00162 natp = getnatp(player->cnum);
00163 if (io_error(player->iop) || io_eof(player->iop)) {
00164 putnat(natp);
00165 return 0;
00166 }
00167 if (player->dolcost > 100.0)
00168 pr("That just cost you $%.2f\n", player->dolcost);
00169 else if (player->dolcost < -100.0)
00170 pr("You just made $%.2f\n", -player->dolcost);
00171 natp->nat_money -= roundavg(player->dolcost);
00172 player->dolcost = 0.0;
00173
00174 old_nstat = player->nstat;
00175 player_set_nstat(player, natp);
00176 if ((old_nstat & MONEY) && !(player->nstat & MONEY))
00177 pr("You are now broke; industries are on strike.\n");
00178 if (!(old_nstat & MONEY) && (player->nstat & MONEY))
00179 pr("You are no longer broke!\n");
00180
00181 time(&player->curup);
00182 minute = (player->curup - player->lasttime) / 60;
00183 if (minute > 0) {
00184 player->minleft -= minute;
00185 if (player->minleft <= 0) {
00186
00187
00188
00189
00190 daychange(player->curup);
00191 if (!gamehours(player->curup)) {
00192 pr("Empire hours restriction in force\n");
00193 if (natp->nat_stat != STAT_GOD) {
00194 putnat(natp);
00195 return 0;
00196 }
00197 }
00198 player->minleft = getminleft(player->curup, m_m_p_d);
00199 }
00200 player->lasttime += minute * 60;
00201 natp->nat_minused += minute;
00202 }
00203 if (natp->nat_stat == STAT_ACTIVE && natp->nat_minused > m_m_p_d) {
00204 pr("Max minutes per day limit exceeded.\n");
00205 player->nstat = (player->nstat & ~NORM) | VIS;
00206 }
00207 if (player->btused) {
00208 natp->nat_btu -= player->btused;
00209 player->btused = 0;
00210 }
00211 if (natp->nat_tgms > 0) {
00212 if (!(natp->nat_flags & NF_INFORM)) {
00213 if (natp->nat_tgms == 1)
00214 pr("You have a new telegram waiting ...\n");
00215 else
00216 pr("You have %s new telegrams waiting ...\n",
00217 numstr(buf, natp->nat_tgms));
00218 natp->nat_tgms = 0;
00219 }
00220 }
00221 if (natp->nat_ann > 0) {
00222 if (natp->nat_ann == 1)
00223 pr("You have a new announcement waiting ...\n");
00224 else
00225 pr("You have %s new announcements waiting ...\n",
00226 numstr(buf, natp->nat_ann));
00227 natp->nat_ann = 0;
00228 }
00229 if (natp->nat_stat == STAT_ACTIVE && (player->nstat & CAP) == 0)
00230 pr("You lost your capital... better designate one\n");
00231 putnat(natp);
00232 if (gamedown() && !player->god) {
00233 pr("gamedown\n");
00234 return 0;
00235 }
00236 return 1;
00237 }
00238
00239
00240
00241
00242
00243
00244 int
00245 execute(void)
00246 {
00247 char buf[1024];
00248 int failed;
00249 char *p;
00250 char *redir;
00251 char scanspace[1024];
00252
00253 failed = 0;
00254
00255 if (player->comtail[1])
00256 p = player->comtail[1];
00257 else
00258 p = getstring("File? ", buf);
00259 if (p == NULL || *p == '\0')
00260 return RET_SYN;
00261 prexec(p);
00262
00263 while (!failed && status()) {
00264 player->nstat &= ~EXEC;
00265 if (recvclient(buf, sizeof(buf)) < 0)
00266 break;
00267 if (parse(buf, scanspace, player->argp, player->comtail,
00268 &player->condarg, &redir) < 0) {
00269 failed = 1;
00270 continue;
00271 }
00272 pr("\nExecute : %s\n", buf);
00273 if (redir) {
00274 pr("Execute : redirection not supported\n");
00275 failed = 1;
00276 } else if (dispatch(buf, NULL) < 0)
00277 failed = 1;
00278 }
00279 if (failed) {
00280 while (recvclient(buf, sizeof(buf)) >= 0) ;
00281 }
00282
00283 pr("Execute : %s\n", failed ? "aborted" : "terminated");
00284 player->eof = 0;
00285 return RET_OK;
00286 }
00287
00288 int
00289 show_motd(void)
00290 {
00291 FILE *motd_fp;
00292 struct telstr tgm;
00293 char buf[MAXTELSIZE + 1];
00294
00295 if ((motd_fp = fopen(motdfil, "rb")) == NULL) {
00296 if (errno == ENOENT)
00297 return RET_OK;
00298 else {
00299 pr ("Could not open motd.\n");
00300 logerror("Could not open motd (%s).\n", motdfil);
00301 return RET_SYS;
00302 }
00303 }
00304 if (fread(&tgm, sizeof(tgm), 1, motd_fp) != 1) {
00305 logerror("bad header on login message (motdfil)");
00306 fclose(motd_fp);
00307 return RET_FAIL;
00308 }
00309 if (tgm.tel_length >= (long)sizeof(buf)) {
00310 logerror("text length (%ld) is too long for login message (motdfil)", tgm.tel_length);
00311 fclose(motd_fp);
00312 return RET_FAIL;
00313 }
00314 if (fread(buf, tgm.tel_length, 1, motd_fp) != 1) {
00315 logerror("bad length %ld on login message", tgm.tel_length);
00316 fclose(motd_fp);
00317 return RET_FAIL;
00318 }
00319 buf[tgm.tel_length] = 0;
00320 uprnf(buf);
00321 fclose(motd_fp);
00322 return RET_OK;
00323 }
00324
00325 int
00326 quit(void)
00327 {
00328 player->state = PS_SHUTDOWN;
00329 return RET_OK;
00330 }
00331
00332 char *
00333 praddr(struct player *p)
00334 {
00335 return prbuf("%s@%s", p->userid,
00336 *p->hostname ? p->hostname : p->hostaddr);
00337 }