Skip to content

Instantly share code, notes, and snippets.

@hdon
Created December 5, 2014 13:36
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save hdon/b79c4f2de67b0123856f to your computer and use it in GitHub Desktop.
Save hdon/b79c4f2de67b0123856f to your computer and use it in GitHub Desktop.
A toy I wrote for Urban Terror
#!/usr/bin/gsr
var prg = "./ioUrbanTerror.i386";
//prg = "/usr/bin/env";
const PTRSIZE = 8;
const ffi = require("gffi");
const signal = require("signal");
const {ByteArray,ByteString} = require("binary");
const {include} = require("./include");
const {Reader} = require("./readline");
const {openDescriptor} = require("fs-base");
const {env} = require("system");
ffi.Memory.prototype.intAt = ByteString.prototype.xintAt;
eval(include(["void perror *","pid_t forkpty * * * *", "* memset * int size_t", "int execve * * *", "int sched_yield",
"* strcpy * *", "* strcat * *", "* strdup *", "int select int * * * *", "void FD_ZERO *", "void FD_SET int *"]));
function syserr(s) {
_perror(s);
throw new Error('abort');
}
function random(a) {
if (a instanceof Array)
return a[Math.floor(Math.random()*a.length)];
}
// program start!
function dupenv() {
var entries = [];
//print('doing env');
for (var k in env) {
var entry = new ffi.Memory(k.length+env[k].length+2);
_strcpy(entry, k);
_strcat(entry, '=');
_strcat(entry, env[k]);
entries.push(entry);
//print(entry.toString());
}
//print('env done');
var envs = new ByteArray(PTRSIZE * (entries.length+1));
for(var i=0; i<entries.length; i++) {
envs.xptrAt(PTRSIZE * i, entries[i].toString());
}
envs.xptrAt(PTRSIZE * entries.length, "@0x0");
/*for(var i=0; i<entries.length; i++) {
print(entries[i].toString() == envs.xptrAt(PTRSIZE * i));
}*/
return envs;
}
var ptyFD = new ffi.Memory(16);
var childPID = _forkpty(ptyFD, null, null, null);
if (childPID == -1)
syserr("fork()");
if (childPID == 0) {
var args = new ByteArray(PTRSIZE*2);
var envs = dupenv();
args.xptrAt(0, _strdup(prg));
args.xptrAt(PTRSIZE, "@0x0");
print('execve() time');
_execve(prg, args, envs);
} else {
/* Exit when the child process exits */
signal.onCHLD = function onCHLD(){
print("Received SIGCHLD -- Exiting");
throw 0;
};
var lastTrigger = 0;
// blue characters: Adala, Carla, Tom, Takeshi
// red characters: Sarah, Misu, Rafiq, Denzel
var funstuff = 'bartsbl bartsgd bartsgn bartsny bartspp blonde capbl capdg capwt capyw eyepatch1 gasmask ninja patch phat piratehat ponybl ponydg ponygd ponyny ponypp shades touqbl touqdg touqwt viking:asian bartsbl bartsgd bartsgn bartsny bartspp capbl capdg capwt capyw gasmask ninja patch phat ponybl ponydg ponygd ponyny ponypp shades touqbl touqdg touqwt viking:capbl capdg capwt capyw cigar foo fringe gasmask goateebk goateerd goggles hndlebk hndlerd mohwkpp mohwkrd mustbk mustrd ninja patch pbeardbl pbeardgn pbeardwt pbeardyw pbeard phat piratehat spikeypp spikeyrd thinbk thinrd touqbl touqdg touqwt viking:capbl capdg capwt capyw cigar foo fringe gasmask goateebk goateerd goggles hndlebk hndlerd mohwkbk mohwkbl mustbk mustrd ninja patch pbeardbl pbeardgn pbeardwt pbeardyw pbeard phat spikeybk spikeybl thinbk thinrd touqbl touqdg touqwt viking/bartsbk bartsgn bartsor bartspk bartsrd capbk capgn capor caprd cears Diablo eyepatch1 ninja patch phat pimpbk pimpgn pimpor pimppk pimprd piratehat ponybk ponygn ponyor ponypk ponyrd shades touqbk touqgn touqrd viking:arab bartsbk bartsgn bartsor bartspk bartsrd black capbk capgn capor caprd cears Diablo ninja patch pimpbk pimpgn pimpor pimppk pimprd ponybk ponygn ponyor ponypk ponyrd shades touqbk touqgn touqrd viking:capbk capgn capor caprd cigar Diablo foo fringe goateebk goateerd goggles hndlebk hndlerd jason mohwkbk mohwkor mustbk mustrd ninja patch pbeardgn pbeardrd pbeardwt pbeardyw pbeard pimpbk pimpgn pimpor pimppk pimprd piratehat spikeybk spikeor thinbk thinrd touqbk touqgn touqrd viking white:capbk capgn capor caprd cigar Diablo foo fringe goateebk goateerd goggles hndlebk hndlerd mohwkbk mohwkor mustbk mustrd ninja patch pbeardgn pbeardrd pbeardwt pbeardyw pbeard pimpbk pimpgn pimpor pimppk pimprd spikeybk spikeyor thinbk thinrd touqbk touqgn touqrd viking white'.split('/').map(function(x){return x.split(':').map(function(x){return x.split(' ')})});
var teamNum = 0;
var teamColor = 'blue';
var charNum = 0;
var charOrder = [0,2,1,3];
var changeCharOrFun = false;
var interval = 10000;
ptyFD = ptyFD.intAt(0);
var pty = openDescriptor(ptyFD, {read:true,write:true,append:true});
print(' starting loop on child data from fd', ptyFD);
function cmd(s) {
//s = 'echo ' + s;
//print('<< ',s);
pty.writeln(s);
if (s.substr(0,5) == 'echo ')
return;
s = 'echo ' + s;
pty.writeln(s);
}
var tv = new ffi.MutableStruct("struct timeval");
var FDs = new ffi.MutableStruct("fd_set");
while (1) {
if (interval) {
tv.tv_sec = Math.floor(interval / 1000);
tv.tv_usec = Math.floor(interval * 10 % 10000);
}
_FD_ZERO(FDs);
_FD_SET(ptyFD, FDs);
var selectResult = _select(ptyFD+1, FDs, null, null, interval?tv:null);
/* Timing system to output to our child process on a regular interval */
if (lastTrigger != 0 && ((lastTrigger + interval) < Date.now())) {
if (!changeCharOrFun) {
charNum = charOrder[(charOrder.indexOf(charNum)+1)%charOrder.length];
cmd('race' + teamColor + ' ' + charNum);
} else {
cmd('fun' + teamColor + ' ' + random(funstuff[teamNum][charNum]));
}
changeCharOrFun = ! changeCharOrFun;
lastTrigger = Date.now();
}
/* Deal with input from the child process */
if (selectResult) {
var line = pty.readln();
if (line) { // TODO select()
if (line.indexOf('+scanner red')>=0) {
lastTrigger = interval + Date.now();
teamColor = 'red';
teamNum = 1;
cmd('echo -------------- Initializing Scanner System --------------');
} else if (line.indexOf('+scanner blue')>=0) {
lastTrigger = 1000 + Date.now();
teamColor = 'blue';
teamNum = 0;
cmd('echo -------------- Initializing Scanner System --------------');
} else if (line.indexOf('+scanner debug')>=0) {
cmd('echo +++ Scanner: Race is '+teamColor+'. Interval is '+interval+' ms.');
} else if (line.indexOf('+scanner int') >= 0) {
interval = parseInt(line.substr(line.indexOf('+scanner int')+13));
cmd('echo +++ Scanner: Interval set at '+interval+' ms');
} else if (line.indexOf('+scanner stop') >= 0) {
interval = 0;
cmd('echo -------------- Stopping the Scanner System --------------');
}
switch (line.trim()) {
case 'hi':
print('<< say Hello');
pty.writeln("say Hello");
break;
default:
print('>> ',line.trim());
}
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment