16 using namespace forest;
40 int main(
int argc,
char *argv[]) {
41 ipa_t myIpAdr, cliMgrIpAdr;
47 sscanf(argv[4],
"%d", &firstComt) != 1 ||
48 sscanf(argv[5],
"%d", &lastComt) != 1 ||
49 sscanf(argv[8],
"%d", &finTime) != 1)
50 fatal(
"usage: Avatar myIpAdr cliMgrIpAdr walls "
51 "firstComt lastComt uname pword finTime");
52 Avatar avatar(myIpAdr,firstComt,lastComt);
53 string uname = string(argv[6]);
54 string pword = string(argv[7]);
55 char* wallsFile = argv[3];
56 if (!avatar.init(cliMgrIpAdr,uname,pword,wallsFile))
57 fatal(
"Avatar:: initialization failure");
58 avatar.run(1000000*finTime);
70 :
myIp(mipa), firstComt(fc), lastComt(lc) {
100 cerr <<
"Avatar::init: could not open/configure forest "
109 cerr <<
"Avatar::init: could not open/configure external "
121 if (!
login(cmIpAdr, uname, pword))
return false;
145 cerr <<
"logging in\n";
150 cerr <<
"Avatar::login: cannot open/configure socket to "
155 string s =
"Forest-login-v1\nlogin: " + uname +
156 "\npassword: " + pword +
"\nover\n";
157 cerr <<
"login string " << s << endl;
161 if (!buf.
readLine(s0) || s0 !=
"success" ||
162 !buf.
readLine(s1) || s1 !=
"over") {
167 s =
"newSession\nover\n";
197 if (!buf.
readLine(s0) || (s0 !=
"over" && s0 !=
"overAndOut"))
206 cout <<
"nonce=" <<
nonce << endl;
216 ifstream ifs(wallsFile);
218 cerr <<
"setupWalls: cannot open walls file\n";
222 bool horizRow =
true;
231 }
catch(exception& e) {
232 cerr <<
"setupWalls: could not allocate space "
233 "for walls array (worldSize="
238 }
else if ((
int) line.size()/2 !=
worldSize) {
239 cerr <<
"setupWalls: format error, all lines must have "
243 for(
int xx = 0; xx < 2*
worldSize; xx++) {
244 int pos = y * worldSize + xx/2;
246 if (!(xx&1))
continue;
247 if (line[xx] ==
'-')
walls[pos] |= 2;
251 if (line[xx] ==
'x')
walls[pos] |= 4;
252 }
else if (line[xx] ==
'|')
walls[pos] |= 1;
254 horizRow = !horizRow;
275 prevVisVec[0] =
true;
277 for (
int d = 1; d <= dlimit; d++) {
279 for (
int x2 = x1; x2 <= min(x1+d,
worldSize-1); x2++) {
280 int y2 = d + y1 - (x2 - x1);
284 if ((x1==x2 && !prevVisVec[dx]) ||
285 (x1!=x2 && y1==y2 && !prevVisVec[dx-1]) ||
286 (x1!=x2 && y1!=y2 && !prevVisVec[dx-1] &&
299 for (
int x2 = x1; x2 <= min(x1+d,
worldSize-1); x2++) {
300 prevVisVec[x2-x1] = visVec[x2-x1];
304 prevVisVec[0] =
true;
305 for (
int d = 1; d <= dlimit; d++) {
307 for (
int x2 = x1; x2 >= max(x1-d,0); x2--) {
309 int y2 = d + y1 - dx;
312 if ((x1==x2 && !prevVisVec[dx]) ||
313 (x1!=x2 && y1==y2 && !prevVisVec[dx-1]) ||
314 (x1!=x2 && y1!=y2 && !prevVisVec[dx-1] &&
326 for (
int x2 = x1; x2 >= max(x1-d,0); x2--) {
328 prevVisVec[dx] = visVec[dx];
332 prevVisVec[0] =
true;
333 for (
int d = 1; d <= dlimit; d++) {
335 for (
int x2 = x1; x2 >= max(x1-d,0); x2--) {
337 int y2 = (y1 - d) + dx;
338 if (y2 < 0)
continue;
340 if ((x1==x2 && !prevVisVec[dx]) ||
341 (x1!=x2 && y1==y2 && !prevVisVec[dx-1]) ||
342 (x1!=x2 && y1!=y2 && !prevVisVec[dx-1] &&
354 for (
int x2 = x1; x2 >= max(x1-d,0); x2--) {
356 prevVisVec[dx] = visVec[dx];
360 prevVisVec[0] =
true;
361 for (
int d = 1; d <= dlimit; d++) {
363 for (
int x2 = x1; x2 <= min(x1+d,
worldSize-1); x2++) {
365 int y2 = (y1 - d) + dx;
366 if (y2 < 0)
continue;
368 if ((x1==x2 && !prevVisVec[dx]) ||
369 (x1!=x2 && y1==y2 && !prevVisVec[dx-1]) ||
370 (x1!=x2 && y1!=y2 && !prevVisVec[dx-1] &&
382 for (
int x2 = x1; x2 <= min(x1+d,
worldSize-1); x2++) {
384 prevVisVec[dx] = visVec[dx];
387 delete [] visVec;
delete [] prevVisVec;
404 uint32_t lastComtSwitch;
407 uint32_t comtSwitchTime = now+1;
410 bool waiting4switch =
false;
411 while (finishTime == 0 || now <= finishTime) {
419 if (newComt != 0 && newComt !=
comt) {
421 waiting4switch =
true;
426 while ((px =
receive()) != 0) {
429 if (waiting4switch) {
446 key = (key << 32) | p.
srcAdr;
455 if (!waiting4switch) {
463 }
else if (
comt == 0 ||
464 now-comtSwitchTime < ((
unsigned) 1)<<31) {
466 lastComtSwitch = now;
467 comt_t newComt = randint(firstComt, lastComt);
468 if (
comt != newComt) {
470 waiting4switch =
true;
472 comtSwitchTime = now + randint(10,30)*1000000;
479 useconds_t delay = nextTime - now;
480 if (delay < ((uint32_t) 1) << 31) usleep(delay);
527 cerr <<
"completeSwitch: failed while "
528 "attempting to leave " <<
comt
529 <<
" (timeout)" << endl;
540 if (cp.type == CtlPkt::CLIENT_LEAVE_COMTREE) {
541 if (cp.mode == CtlPkt::POS_REPLY) {
547 }
else if (cp.mode == CtlPkt::NEG_REPLY) {
548 cerr <<
"completeSwitch: failed while "
549 "attempting to leave " <<
comt
550 <<
" (request rejected)" << endl;
559 cerr <<
"completeSwitch: failed while "
560 "attempting to join " <<
comt
561 <<
" (timeout)" << endl;
572 if (cp.type == CtlPkt::CLIENT_JOIN_COMTREE) {
573 if (cp.mode == CtlPkt::POS_REPLY) {
576 }
else if (cp.mode == CtlPkt::NEG_REPLY) {
577 cerr <<
"completeSwitch: failed while "
578 "attempting to join " <<
comt
579 <<
" (request rejected)" << endl;
595 if (
comt == 0)
return;
601 uint32_t *pp = p.payload();
607 pp[5] = htonl((uint32_t)
speed);
622 if (
comt == 0)
return;
624 buf[0] = htonl((uint32_t) now);
625 buf[8] = htonl((uint32_t)
comt);
626 buf[9] = htonl(avType);
628 buf[1] = htonl((uint32_t)
myAdr);
629 buf[2] = htonl((uint32_t)
x);
630 buf[3] = htonl((uint32_t)
y);
632 buf[5] = htonl((uint32_t)
speed);
634 buf[7] = htonl((uint32_t)
numNear);
635 }
else if (px != 0) {
637 uint32_t *pp = p.payload();
651 char *bp= (
char *) buf;
653 int n = write(
connSock, (
void *) bp, nbytes);
654 if (n < 0) fatal(
"Avatar::forwardReport: failure in write");
655 bp += n; nbytes -= n;
666 fatal(
"Avatar::send2comtCtl: no packets left to allocate");
669 CtlPkt cp(joinLeave,CtlPkt::REQUEST,
seqNum,p.payload());
675 fatal(
"Avatar::send2comtCtl: control packet packing error");
708 fatal(
"can't make connection socket nonblocking");
709 bool status;
int ndVal = 1;
710 status = setsockopt(
listenSock,IPPROTO_TCP,TCP_NODELAY,
711 (
void *) &ndVal,
sizeof(
int));
713 cerr <<
"setsockopt for no-delay failed\n";
719 int nbytes = read(
connSock, buf, 5);
721 if (errno == EAGAIN)
return 0;
722 fatal(
"Avatar::check4command: error in read call");
723 }
else if (nbytes == 0) {
727 }
else if (nbytes < 5) {
728 fatal(
"Avatar::check4command: incomplete command");
731 uint32_t param = ntohl(*((
int*) &buf[1]));
747 case 'c':
return param;
759 p.payload()[0] = htonl((uint32_t) (
nonce >> 32));
760 p.payload()[1] = htonl((uint32_t) (
nonce & 0xffffffff));
762 p.
comtree = Forest::CONNECT_COMT;
769 if (now > resendTime) {
770 if (resendCount > 3) {
ps->
free(px);
return false; }
772 resendTime += 1000000;
776 if (rx == 0) { usleep(100000);
continue; }
791 p.payload()[0] = htonl((uint32_t) (
nonce >> 32));
792 p.payload()[1] = htonl((uint32_t) (
nonce & 0xffffffff));
801 if (now > resendTime) {
802 if (resendCount > 3) {
ps->
free(px);
return false; }
804 resendTime += 1000000;
808 if (rx == 0) { usleep(100000);
continue; }
827 if (rv == -1) fatal(
"Avatar::send: failure in sendto");
835 if (px == 0)
return 0;
838 ipa_t remoteIp; ipp_t remotePort;
840 remoteIp, remotePort);
842 if (errno == EWOULDBLOCK) {
845 fatal(
"Avatar::receive: error in recvfrom call");
870 const double PI = 3.141519625;
877 int x1 =
x + (int) (dist * sin(dirRad));
878 int y1 =
y + (int) (dist * cos(dirRad));
882 (prevRegion != postRegion &&
883 (
walls[postRegion]&4 ||
888 if (postRegion != prevRegion) updateVisSet();
894 bool atLeft = (prevRegion%
worldSize == 0);
896 bool atBot = (prevRegion/
worldSize == 0);
899 if (xd < .25*
GRID && (atLeft ||
walls[prevRegion]&1 ||
900 walls[prevRegion-1]&4)) {
905 }
else if (xd > .75*
GRID && (atRight ||
walls[prevRegion+1]&1 ||
906 walls[prevRegion+1]&4)) {
917 }
else if (yd > .75*
GRID && (atTop ||
walls[prevRegion]&2 ||
928 if ((r = randfrac()) < 0.1) {
929 if (r < .05)
deltaDir -= 0.2 * randfrac();
935 if ((r = randfrac()) <= 0.1) {
946 x += (int) (dist * sin(dirRad));
947 y += (int) (dist * cos(dirRad));
949 if (postRegion != prevRegion) updateVisSet();
958 if (c0 > c1) {
int temp = c1; c1 = c0; c0 = temp; }
963 else if (c0%worldSize > c1%worldSize) {
964 if ((
walls[c0]&3) == 3 ||
997 int sq1 = g1-1;
int sq2 = g2-1;
1003 int x = x1; x1 = x2; x2 =
x;
1004 int y = y1; y1 = y2; y2 =
y;
1008 int lo = min(y1, y2);
int hi = max(y1, y2);
1009 for (
int y = lo;
y < hi;
y++) {
1013 }
else if (y1 == y2) {
1014 for (
int x = x1+1;
x <= x2;
x++) {
1020 const double eps = .001;
1021 double sq1xs[] = {x1+eps, x1+(1.0-eps),x1+eps,x1+(1.0-eps)};
1022 double sq1ys[] = {y1+(1.0-eps),y1+(1.0-eps),y1+eps,y1+eps };
1023 double sq2xs[] = {x2+eps, x2+(1.0-eps),x2+eps,x2+(1.0-eps)};
1024 double sq2ys[] = {y2+(1.0-eps),y2+(1.0-eps),y2+eps,y2+eps };
1026 int miny = min(y1,y2);
int maxy = max(y1,y2);
1027 double slope = (y2-y1)/((
double) x2-x1);
1029 for (
int i = 0; i < 4; i++) {
1030 for (
int j = 0; j < 4; j++) {
1032 double ax = sq1xs[i];
double ay = sq1ys[i];
1033 double bx = sq2xs[j];
double by = sq2ys[j];
1035 for (
int x = x1;
x <= x2 && canSee;
x++) {
1036 int lo = miny;
int hi = maxy;
1038 lo = (
x==x1 ? y1 : (int) ((
x-(x1+1))*slope + y1));
1039 hi = ((
x+1)-x1)*slope + (y1+1);
1040 lo = max(lo,y1); hi = min(hi,y2);
1042 lo = ((
x+1)-x1)*slope + y1;
1043 hi = (
x==x1 ? y1-1 : (int) ((
x-(x1+1))*slope + (y1+1)));
1044 lo = max(lo,y2); hi = min(hi,y1);
1046 for (
int y = lo;
y <= hi;
y++) {
1047 double cx = (double)
x;
1048 double cy = (double) (
y+1);
1054 double dx = cx;
double dy = cy-1;
1055 if (linesIntersect(ax,ay,bx,by,cx,cy,dx,dy)) {
1056 canSee =
false;
break;
1062 double dx = cx+1;
double dy = cy;
1063 if (linesIntersect(ax,ay,bx,by,cx,cy,dx,dy)) {
1064 canSee =
false;
break;
1068 if (canSee)
return true;
1073 bool Avatar::linesIntersect(
double ax,
double ay,
double bx,
double by,
1074 double cx ,
double cy,
double dx,
double dy) {
1075 double epsilon = .001;
1078 if (abs(ax-bx) < epsilon && abs(cx-dx) < epsilon) {
1079 return abs(ax-cx) < epsilon && max(ay,by) >= min(cy,dy)
1080 && min(ay,by) <= max(cy,dy);
1083 if (abs(ax-bx) < epsilon) {
1084 double s2 = (dy-cy)/(dx-cx);
1085 double i2 = cy - s2*cx;
1086 double y = s2*ax + i2;
1087 return (y >= min(ay,by) && y <= max(ay,by) &&
1088 y >= min(cy,dy) && y <= max(cy,dy));
1090 if (abs(cx-dx) < epsilon) {
1091 double s1 = (by-ay)/(bx-ax);
1092 double i1 = ay - s1*ax;
1093 double y = s1*cx + i1;
1094 return (y >= min(ay,by) && y <= max(ay,by) &&
1095 y >= min(cy,dy) && y <= max(cy,dy));
1097 double s1 = (by-ay)/(bx-ax);
1098 double i1 = ay - s1*ax;
1099 double s2 = (dy-cy)/(dx-cx);
1100 double i2 = cy - s2*cx;
1105 if (abs(s1)+abs(s2) <= epsilon ||
1106 abs(s1-s2)/(abs(s1)+abs(s2)) < epsilon) {
1107 return (abs(i1-i2) < epsilon &&
1108 min(ax,bx) <= max(cx,dx) && max(ax,bx) >= min(cx,dx));
1111 double x = (i2-i1)/(s1-s2);
1113 return (x >= min(ax,bx) && x <= max(ax,bx) &&
1114 x >= min(cx,dx) && x <= max(cx,dx));
1117 void Avatar::subscribe(list<int>& glist) {
1118 if (
comt == 0 || glist.size() == 0)
return;
1121 uint32_t *pp = p.payload();
1124 list<int>::iterator gp;
1125 for (gp = glist.begin(); gp != glist.end(); gp++) {
1126 int g = *gp; nsub++;
1128 pp[0] = htonl(nsub-1); pp[nsub] = 0;
1136 pp[nsub] = htonl(-g);
1138 pp[0] = htonl(nsub); pp[nsub+1] = 0;
1151 if (
comt == 0 || glist.size() == 0)
return;
1154 uint32_t *pp = p.payload();
1157 list<int>::iterator gp;
1158 for (gp = glist.begin(); gp != glist.end(); gp++) {
1159 int g = *gp; nunsub++;
1161 pp[0] = 0; pp[1] = htonl(nunsub-1);
1169 pp[nunsub+1] = htonl(-g);
1171 pp[0] = 0; pp[1] = htonl(nunsub);
1184 set<int>::iterator gp;
1187 mySubs->insert(*gp); glist.push_back(*gp);
1197 set<int>::iterator gp;
1199 glist.push_back(*gp);
1212 set<int>::iterator gp;
1213 for (gp =
mySubs->begin(); gp !=
mySubs->end(); gp++) {
1219 list<int>::iterator p;
1220 for (p = glist.begin(); p != glist.end(); p++)
1227 set<int>::iterator vp;
1250 uint32_t *pp = p.payload();
1254 uint64_t avId = p.
srcAdr; avId = (avId << 32) | p.
srcAdr;
1259 int x1 = ntohl(pp[2]);
int y1 = ntohl(pp[3]);
1271 set<int>::iterator vp;
1272 int minx = min(x,x1)/
GRID;
int maxx = max(x,x1)/
GRID;
1273 int miny = min(y,y1)/
GRID;
int maxy = max(y,y1)/
GRID;
1277 if (xi < minx || xi > maxx || yi < miny || yi > maxy)
1280 int ax = xi;
int ay = yi +
GRID;
1282 if(linesIntersect(x,y,x1,y1,ax,ay,ax+GRID,ay)) {
1283 canSee =
false;
break;
1287 if(linesIntersect(x,y,x1,y1,ax,ay,ax,ay-GRID)) {
1288 canSee =
false;
break;
1326 void Avatar::updateVisSet() {