105 #include <sys/types.h>
106 #include <sys/socket.h>
107 #include <sys/wait.h>
160 static void send_map(
int i,
int x,
int y);
171 #define write(x, y, z) emulate_write(x, y, z)
172 #define read(x, y, z) emulate_read(x, y, z)
174 static int emulate_read(HANDLE fd,
char *buf,
int len)
179 FlushFileBuffers(fd);
180 rc = ReadFile(fd, buf, len, &dwBytesRead, NULL);
184 buf[dwBytesRead] =
'\0';
189 static int emulate_write(HANDLE fd,
const char *buf,
int len)
191 DWORD dwBytesWritten;
194 rc = WriteFile(fd, buf, len, &dwBytesWritten, NULL);
195 FlushFileBuffers(fd);
200 return(dwBytesWritten);
207 int pipe1[2], pipe2[2];
213 "Please specify a script to start. For help, type "
225 while (*args && *args !=
' ') {
228 while (*args && *args ==
' ') {
236 if (pipe(pipe1) != 0) {
238 "Unable to start script--pipe failed");
241 if (pipe(pipe2) != 0) {
246 "Unable to start script--pipe failed");
258 "Unable to start script--fork failed");
271 while (args && *args && i <
sizeof(argv)/
sizeof(*argv)-1) {
273 while (*args && *args !=
' ') {
276 while (*args && *args ==
' ') {
283 r = dup2(pipe1[0], 0);
285 fprintf(stderr,
"Script Child: Failed to set pipe1 as stdin\n");
287 r = dup2(pipe2[1], 1);
289 fprintf(stderr,
"Script Child: Failed to set pipe2 as stdout\n");
291 for (i = 3; i < 100; ++i) {
300 r = execvp(argv[0], argv);
309 printf(
"draw %d Could not start script: %s\n",
NDI_RED, strerror(errno));
317 if (fcntl(pipe1[1], F_SETFL, O_NDELAY) == -1) {
326 "Could not allocate memory: %s", strerror(errno));
345 SECURITY_ATTRIBUTES saAttr;
346 PROCESS_INFORMATION piProcInfo;
347 STARTUPINFO siStartupInfo;
348 HANDLE hChildStdinRd, hChildStdinWr, hChildStdinWrDup, hChildStdoutRd;
349 HANDLE hChildStdoutWr, hChildStdoutRdDup, hSaveStdin, hSaveStdout;
353 "Please specifiy a script to launch!");
363 while (*args && *args !=
' ') {
366 while (*args && *args ==
' ') {
373 saAttr.nLength =
sizeof(SECURITY_ATTRIBUTES);
374 saAttr.bInheritHandle = TRUE;
375 saAttr.lpSecurityDescriptor = NULL;
377 hSaveStdout = GetStdHandle(STD_OUTPUT_HANDLE);
378 if (!CreatePipe(&hChildStdoutRd, &hChildStdoutWr, &saAttr, 0)) {
380 "Script support: stdout CreatePipe() failed");
384 if (!SetStdHandle(STD_OUTPUT_HANDLE, hChildStdoutWr)) {
386 "Script support: failed to redirect stdout using SetStdHandle()");
390 if (!DuplicateHandle(GetCurrentProcess(), hChildStdoutRd, GetCurrentProcess(), &hChildStdoutRdDup, 0, FALSE, DUPLICATE_SAME_ACCESS)) {
392 "Script support: failed to duplicate stdout using DuplicateHandle()");
396 CloseHandle(hChildStdoutRd);
398 hSaveStdin = GetStdHandle(STD_INPUT_HANDLE);
399 if (!CreatePipe(&hChildStdinRd, &hChildStdinWr, &saAttr, 0)) {
401 "Script support: stdin CreatePipe() failed");
405 if (!SetStdHandle(STD_INPUT_HANDLE, hChildStdinRd)) {
407 "Script support: failed to redirect stdin using SetStdHandle()");
411 if (!DuplicateHandle(GetCurrentProcess(), hChildStdinWr, GetCurrentProcess(), &hChildStdinWrDup, 0, FALSE, DUPLICATE_SAME_ACCESS)) {
413 "Script support: failed to duplicate stdin using DuplicateHandle()");
417 CloseHandle(hChildStdinWr);
419 ZeroMemory(&piProcInfo,
sizeof(PROCESS_INFORMATION));
420 ZeroMemory(&siStartupInfo,
sizeof(STARTUPINFO));
421 siStartupInfo.cb =
sizeof(STARTUPINFO);
427 if (!CreateProcess(NULL,
name, NULL, NULL, TRUE, CREATE_NEW_PROCESS_GROUP, NULL, NULL, &siStartupInfo, &piProcInfo)) {
429 "Script support: CreateProcess() failed");
433 CloseHandle(piProcInfo.hThread);
439 if (!SetStdHandle(STD_INPUT_HANDLE, hSaveStdin)) {
441 "Script support: restoring original stdin failed");
445 if (!SetStdHandle(STD_OUTPUT_HANDLE, hSaveStdout)) {
447 "Script support: restoring original stdout failed");
456 "Could not allocate memory: %s", strerror(errno));
486 snprintf(buf,
sizeof(buf),
"sync %d\n", commdiff);
497 "No scripts are currently running");
502 snprintf(buf,
sizeof(buf),
"%d scripts currently running:",
num_scripts);
508 snprintf(buf,
sizeof(buf),
"%d %s", i+1,
scripts[i].
name);
523 "No such running script");
529 GenerateConsoleCtrlEvent(CTRL_BREAK_EVENT,
scripts[i].
pid);
543 const char message_template[] =
"Tried to kill %d scripts.";
544 char message[
sizeof(message_template) + 10];
545 snprintf(message,
sizeof(message), message_template,
num_scripts);
551 GenerateConsoleCtrlEvent(CTRL_BREAK_EVENT,
scripts[0].
pid);
578 DWORD nAvailBytes = 0;
590 bStatus = GetExitCodeProcess(
scripts[i].process, &dwStatus);
591 bRC = PeekNamedPipe(
scripts[i].
in_fd, &cTmp, 1, NULL, &nAvailBytes, NULL);
601 else if (r == 0 || errno == EBADF)
603 else if (r == 0 || GetLastError() == ERROR_BROKEN_PIPE)
625 else if (!bRC || (bStatus && (dwStatus != STILL_ACTIVE))) {
651 snprintf(buf,
sizeof(buf),
"watch %s\n",
cmd);
655 snprintf(buf,
sizeof(buf),
"watch %s %s\n",
cmd, data);
666 be = snprintf(buf,
sizeof(buf),
"watch %s",
cmd);
667 for (p = 0; p*2 < len; ++p) {
668 be += snprintf(buf+be,
sizeof(buf)-be,
" %d",
GetShort_String(data+p*2));
670 be += snprintf(buf+be,
sizeof(buf)-be,
"\n");
678 be = snprintf(buf,
sizeof(buf),
"watch %s",
cmd);
679 for (p = 0; p*4 < len; ++p) {
680 be += snprintf(buf+be,
sizeof(buf)-be,
" %d",
GetInt_String(data+p*4));
682 be += snprintf(buf+be,
sizeof(buf)-be,
"\n");
697 be += snprintf(buf+be,
sizeof(buf)-be,
"watch %s",
cmd);
702 be += snprintf(buf+be,
sizeof(buf)-be,
" resists %d %d\n", c,
GetShort_String(data));
706 be += snprintf(buf+be,
sizeof(buf)-be,
" skill %d %d %" G_GINT64_FORMAT
"\n", c, *data,
GetInt64_String(data+1));
712 be += snprintf(buf+be,
sizeof(buf)-be,
" hp %d\n",
GetShort_String(data));
718 be += snprintf(buf+be,
sizeof(buf)-be,
" maxhp %d\n",
GetShort_String(data));
724 be += snprintf(buf+be,
sizeof(buf)-be,
" sp %d\n",
GetShort_String(data));
730 be += snprintf(buf+be,
sizeof(buf)-be,
" maxsp %d\n",
GetShort_String(data));
736 be += snprintf(buf+be,
sizeof(buf)-be,
" grace %d\n",
GetShort_String(data));
742 be += snprintf(buf+be,
sizeof(buf)-be,
" maxgrace %d\n",
GetShort_String(data));
748 be += snprintf(buf+be,
sizeof(buf)-be,
" str %d\n",
GetShort_String(data));
754 be += snprintf(buf+be,
sizeof(buf)-be,
" int %d\n",
GetShort_String(data));
760 be += snprintf(buf+be,
sizeof(buf)-be,
" pow %d\n",
GetShort_String(data));
766 be += snprintf(buf+be,
sizeof(buf)-be,
" wis %d\n",
GetShort_String(data));
772 be += snprintf(buf+be,
sizeof(buf)-be,
" dex %d\n",
GetShort_String(data));
778 be += snprintf(buf+be,
sizeof(buf)-be,
" con %d\n",
GetShort_String(data));
784 be += snprintf(buf+be,
sizeof(buf)-be,
" cha %d\n",
GetShort_String(data));
790 be += snprintf(buf+be,
sizeof(buf)-be,
" exp %d\n",
GetInt_String(data));
796 be += snprintf(buf+be,
sizeof(buf)-be,
" exp %" G_GINT64_FORMAT
"\n",
GetInt64_String(data));
802 be += snprintf(buf+be,
sizeof(buf)-be,
" level %d\n",
GetShort_String(data));
808 be += snprintf(buf+be,
sizeof(buf)-be,
" wc %d\n",
GetShort_String(data));
814 be += snprintf(buf+be,
sizeof(buf)-be,
" ac %d\n",
GetShort_String(data));
820 be += snprintf(buf+be,
sizeof(buf)-be,
" dam %d\n",
GetShort_String(data));
826 be += snprintf(buf+be,
sizeof(buf)-be,
" armour %d\n",
GetShort_String(data));
832 be += snprintf(buf+be,
sizeof(buf)-be,
" speed %d\n",
GetInt_String(data));
838 be += snprintf(buf+be,
sizeof(buf)-be,
" food %d\n",
GetShort_String(data));
844 be += snprintf(buf+be,
sizeof(buf)-be,
" weap_sp %d\n",
GetInt_String(data));
850 be += snprintf(buf+be,
sizeof(buf)-be,
" flags %d\n",
GetShort_String(data));
856 be += snprintf(buf+be,
sizeof(buf)-be,
" weight_lim %d\n",
GetInt_String(data));
865 be += snprintf(buf+be,
sizeof(buf)-be,
" range %*.*s\n", rlen, rlen, data);
875 be += snprintf(buf+be,
sizeof(buf)-be,
" title %*.*s\n", rlen, rlen, data);
882 be += snprintf(buf+be,
sizeof(buf)-be,
" unknown %d %d bytes left\n", c, len);
913 be = snprintf(buf,
sizeof(buf),
"watch %s %d bytes unparsed:",
cmd, len);
914 for (p = 0; p < len; ++p) {
915 be += snprintf(buf+be,
sizeof(buf)-be,
" %02x", data[p]);
917 be += snprintf(buf+be,
sizeof(buf)-be,
"\n");
937 snprintf(buf,
sizeof(buf),
"monitor %d %d %s\n", repeat, must_send, command);
953 snprintf(buf,
sizeof(buf),
"monitor %s\n", command);
966 "Which script do you want to talk to?");
973 p = strchr(params_cpy,
' ');
976 "What do you want to tell the script?");
987 "No such running script");
1007 if (isdigit(*
name)) {
1017 while (
name[l] &&
name[l] !=
' ') {
1039 CloseHandle(
scripts[i].process);
1049 waitpid(-1, NULL, WNOHANG);
1066 snprintf(buf,
sizeof(buf),
"request map %d %d unknown\n", x, y);
1070 snprintf(buf,
sizeof(buf),
"request map %d %d %d %c %c %c %c"
1071 " smooth %d %d %d heads %d %d %d tails %d %d %d\n",
1101 char *cr = strchr(
cmd,
'\r');
1131 if (strncmp(
cmd,
"sync", 4) == 0) {
1133 while (*c && *c !=
' ') {
1144 }
else if (strncmp(
cmd,
"watch", 5) == 0) {
1146 while (*c && *c !=
' ') {
1156 }
else if (strncmp(
cmd,
"unwatch", 7) == 0) {
1160 while (*c && *c !=
' ') {
1177 }
else if (strncmp(
cmd,
"request", 7) == 0) {
1179 while (*c && *c !=
' ') {
1216 if (strncmp(c,
"player", 6) == 0) {
1219 snprintf(buf,
sizeof(buf),
"request player %d %s\n",
cpl.
ob->
tag,
cpl.
title);
1221 }
else if (strncmp(c,
"range", 5) == 0) {
1224 snprintf(buf,
sizeof(buf),
"request range %s\n",
cpl.
range);
1226 }
else if (strncmp(c,
"weight", 5) == 0) {
1231 }
else if (strncmp(c,
"stat ", 5) == 0) {
1233 while (*c && *c !=
' ') {
1249 if (strncmp(c,
"stats", 5) == 0) {
1254 }
else if (strncmp(c,
"cmbt", 4) == 0) {
1259 }
else if (strncmp(c,
"hp", 2) == 0) {
1264 }
else if (strncmp(c,
"xp", 2) == 0) {
1275 }
else if (strncmp(c,
"resists", 7) == 0) {
1279 snprintf(buf,
sizeof(buf),
"request stat resists");
1281 for (s = 0; s < 30; ++s) {
1286 }
else if (strncmp(c,
"paths", 2) == 0) {
1292 }
else if (strncmp(c,
"flags", 5) == 0) {
1297 }
else if (strncmp(c,
"items ", 6) == 0) {
1299 while (*c && *c !=
' ') {
1314 if (strncmp(c,
"inv", 3) == 0) {
1321 buf =
"request items inv end\n";
1324 if (strncmp(c,
"actv", 4) == 0) {
1333 buf =
"request items actv end\n";
1336 if (strncmp(c,
"on", 2) == 0) {
1343 buf =
"request items on end\n";
1346 if (strncmp(c,
"cont", 4) == 0) {
1355 buf =
"request items cont end\n";
1358 }
else if (strncmp(c,
"map ", 4) == 0) {
1362 while (*c && *c !=
' ') {
1377 if (strncmp(c,
"pos", 3) == 0) {
1380 snprintf(buf,
sizeof(buf),
"request map pos %d %d\n",
1383 }
else if (strncmp(c,
"near", 4) == 0) {
1384 for (y = 0; y < 3; ++y)
1385 for (x = 0; x < 3; ++x)
1390 }
else if (strncmp(c,
"all", 3) == 0) {
1391 char *endmsg =
"request map end\n";
1396 for (y = 0; y < sizey; y++) {
1397 for (x = 0; x < sizex; x++) {
1404 while (*c && !isdigit(*c)) {
1411 while (*c && *c !=
' ') {
1414 while (*c && !isdigit(*c)) {
1423 }
else if (strncmp(c,
"skills", 6) == 0) {
1433 snprintf(buf,
sizeof(buf),
"request skills end\n");
1435 }
else if (strncmp(c,
"spells", 6) == 0) {
1440 snprintf(buf,
sizeof(buf),
"request spells %d %d %d %d %d %d %d %d %s\n",
1446 snprintf(buf,
sizeof(buf),
"request spells end\n");
1451 snprintf(buf,
sizeof(buf),
"Script %d %s malfunction; unimplemented request:", i+1,
scripts[i].
name);
1455 }
else if (strncmp(
cmd,
"issue", 5) == 0) {
1460 while (*c && *c ==
' ') {
1463 if (*c && (isdigit(*c) || *c ==
'-')) {
1465 while (*c && *c !=
' ') {
1468 while (*c && !isdigit(*c) && *c !=
'-') {
1474 must_send = atoi(c);
1475 while (*c && *c !=
' ') {
1491 snprintf(buf,
sizeof(buf),
"Script %d %s malfunction; command not sent", i+1,
scripts[i].
name);
1500 while (*c && *c !=
' ') {
1515 if (strncmp(c,
"mark", 4) == 0) {
1522 while (*c && !isdigit(*c)) {
1534 }
else if (strncmp(c,
"lock", 4) == 0) {
1541 while (*c && !isdigit(*c)) {
1548 while (*c && *c !=
' ') {
1551 while (*c && !isdigit(*c)) {
1564 }
else if ( (strncmp(c,
"take", 4) == 0) || (strncmp(c,
"drop", 4) == 0) ) {
1565 int tag, count, dest;
1567 dest = (strncmp(c,
"drop", 4) == 0) ? 0 :
cpl.
ob->
tag;
1570 while (*c && !isdigit(*c)) {
1577 while (*c && *c !=
' ') {
1580 while (*c && !isdigit(*c)) {
1589 }
else if (strncmp(c,
"apply", 5) == 0) {
1594 while (*c && !isdigit(*c)) {
1607 }
else if (strncmp(
cmd,
"localcmd", 8) == 0) {
1615 while ((*param !=
'\0') && (*param !=
' ')) {
1618 if (*param ==
' ') {
1628 snprintf(buf,
sizeof(buf),
"Script %s malfunction; localcmd not understood",
scripts[i].
name);
1630 snprintf(buf,
sizeof(buf),
"Script <<localcmd %s %s>>", c, (param == NULL) ?
"" : param);
1633 }
else if (strncmp(
cmd,
"draw", 4) == 0) {
1637 while (*c && !isdigit(*c)) {
1644 while (*c && *c !=
' ') {
1654 }
else if (strncmp(
cmd,
"monitor", 7) == 0) {
1656 }
else if (strncmp(
cmd,
"unmonitor", 9) == 0) {
1661 snprintf(buf,
sizeof(buf),
"Script %d %s malfunction; invalid command:", i+1,
scripts[i].
name);
1688 flags = (flags<<1)|it->
magical;
1689 flags = (flags<<1)|it->
cursed;
1690 flags = (flags<<1)|it->
damned;
1691 flags = (flags<<1)|it->
unpaid;
1692 flags = (flags<<1)|it->
locked;
1693 flags = (flags<<1)|it->
applied;
1694 flags = (flags<<1)|it->
open;
1697 snprintf(buf,
sizeof(buf),
"%s%d %d %d %d %d %s\n", head, it->
tag, it->
nrof, (int)(it->
weight*1000+0.5), flags, it->
type, it->
d_name);