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);
73 mySubs =
new set<int>();
74 nearAvatars =
new HashSet(MAXNEAR);
75 visibleAvatars =
new HashSet(MAXNEAR);
76 myVisSet =
new set<int>;
78 numNear = numVisible = 0;
94 bool Avatar::init(ipa_t cmIpAdr,
string& uname,
string& pword,
101 cerr <<
"Avatar::init: could not open/configure forest "
110 cerr <<
"Avatar::init: could not open/configure external "
122 if (!
login(cmIpAdr, uname, pword))
return false;
144 bool Avatar::login(ipa_t cmIpAdr,
string uname,
string pword) {
150 cerr <<
"Avatar::login: cannot open/configure socket to "
155 string s =
"Forest-login-v1\nlogin: " + uname +
156 "\npassword: " + pword +
"\nover\n";
160 if (!buf.readLine(s0) || s0 !=
"success" ||
161 !buf.readLine(s1) || s1 !=
"over") {
166 s =
"newSession\nover\n";
170 if (!buf.readAlphas(s0) || s0 !=
"yourAddress" || !buf.verify(
':') ||
171 !buf.readForestAddress(s1) || !buf.nextLine())
177 if (!buf.readAlphas(s0) || s0 !=
"yourRouter" || !buf.verify(
':') ||
178 !buf.verify(
'(') || !buf.readIpAddress(s1) || !buf.verify(
',') ||
179 !buf.readInt(port) || !buf.verify(
',') ||
180 !buf.readForestAddress(s2) || !buf.verify(
')') || !buf.nextLine())
187 if (!buf.readAlphas(s0) || s0 !=
"comtCtlAddress" || !buf.verify(
':') ||
188 !buf.readForestAddress(s1) || !buf.nextLine())
193 if (!buf.readAlphas(s0) || s0 !=
"connectNonce" || !buf.verify(
':') ||
194 !buf.readInt(
nonce) || !buf.nextLine())
196 if (!buf.readLine(s0) || (s0 !=
"over" && s0 !=
"overAndOut"))
205 cout <<
"nonce=" <<
nonce << endl;
215 ifstream ifs(wallsFile);
217 cerr <<
"setupWalls: cannot open walls file\n";
221 bool horizRow =
true;
230 }
catch(exception& e) {
231 cerr <<
"setupWalls: could not allocate space "
232 "for walls array (worldSize="
237 }
else if ((
int) line.size()/2 !=
worldSize) {
238 cerr <<
"setupWalls: format error, all lines must have "
242 for(
int xx = 0; xx < 2*
worldSize; xx++) {
243 int pos = y * worldSize + xx/2;
245 if (!(xx&1))
continue;
246 if (line[xx] ==
'-')
walls[pos] |= 2;
250 if (line[xx] ==
'x')
walls[pos] |= 4;
251 }
else if (line[xx] ==
'|')
walls[pos] |= 1;
253 horizRow = !horizRow;
266 int x1 = (g1-1)%worldSize;
int y1 = (g1-1)/worldSize;
274 prevVisVec[0] =
true;
275 int dlimit = min(worldSize,
MAX_VIS);
276 for (
int d = 1; d <= dlimit; d++) {
278 for (
int x2 = x1; x2 <= min(x1+d,worldSize-1); x2++) {
279 int y2 = d + y1 - (x2 - x1);
280 if (y2 >= worldSize)
continue;
283 if ((x1==x2 && !prevVisVec[dx]) ||
284 (x1!=x2 && y1==y2 && !prevVisVec[dx-1]) ||
285 (x1!=x2 && y1!=y2 && !prevVisVec[dx-1] &&
298 for (
int x2 = x1; x2 <= min(x1+d,worldSize-1); x2++) {
299 prevVisVec[x2-x1] = visVec[x2-x1];
303 prevVisVec[0] =
true;
304 for (
int d = 1; d <= dlimit; d++) {
306 for (
int x2 = x1; x2 >= max(x1-d,0); x2--) {
308 int y2 = d + y1 - dx;
309 if (y2 >= worldSize)
continue;
311 if ((x1==x2 && !prevVisVec[dx]) ||
312 (x1!=x2 && y1==y2 && !prevVisVec[dx-1]) ||
313 (x1!=x2 && y1!=y2 && !prevVisVec[dx-1] &&
325 for (
int x2 = x1; x2 >= max(x1-d,0); x2--) {
327 prevVisVec[dx] = visVec[dx];
331 prevVisVec[0] =
true;
332 for (
int d = 1; d <= dlimit; d++) {
334 for (
int x2 = x1; x2 >= max(x1-d,0); x2--) {
336 int y2 = (y1 - d) + dx;
337 if (y2 < 0)
continue;
339 if ((x1==x2 && !prevVisVec[dx]) ||
340 (x1!=x2 && y1==y2 && !prevVisVec[dx-1]) ||
341 (x1!=x2 && y1!=y2 && !prevVisVec[dx-1] &&
353 for (
int x2 = x1; x2 >= max(x1-d,0); x2--) {
355 prevVisVec[dx] = visVec[dx];
359 prevVisVec[0] =
true;
360 for (
int d = 1; d <= dlimit; d++) {
362 for (
int x2 = x1; x2 <= min(x1+d,worldSize-1); x2++) {
364 int y2 = (y1 - d) + dx;
365 if (y2 < 0)
continue;
367 if ((x1==x2 && !prevVisVec[dx]) ||
368 (x1!=x2 && y1==y2 && !prevVisVec[dx-1]) ||
369 (x1!=x2 && y1!=y2 && !prevVisVec[dx-1] &&
381 for (
int x2 = x1; x2 <= min(x1+d,worldSize-1); x2++) {
383 prevVisVec[dx] = visVec[dx];
386 delete [] visVec;
delete [] prevVisVec;
403 uint32_t lastComtSwitch;
406 uint32_t comtSwitchTime = now+1;
409 bool waiting4switch =
false;
410 while (finishTime == 0 || now <= finishTime) {
418 if (newComt != 0 && newComt !=
comt) {
420 waiting4switch =
true;
425 while ((px =
receive()) != 0) {
428 if (waiting4switch) {
445 key = (key << 32) | p.
srcAdr;
454 if (!waiting4switch) {
462 }
else if (
comt == 0 ||
463 now-comtSwitchTime < ((
unsigned) 1)<<31) {
465 lastComtSwitch = now;
467 if (
comt != newComt) {
469 waiting4switch =
true;
471 comtSwitchTime = now + randint(1,3)*100000;
478 useconds_t delay = nextTime - now;
479 if (delay < ((uint32_t) 1) << 31) usleep(delay);
526 cerr <<
"completeSwitch: failed while "
527 "attempting to leave " <<
comt
528 <<
" (timeout)" << endl;
539 if (cp.type == CtlPkt::CLIENT_LEAVE_COMTREE) {
540 if (cp.mode == CtlPkt::POS_REPLY) {
546 }
else if (cp.mode == CtlPkt::NEG_REPLY) {
547 cerr <<
"completeSwitch: failed while "
548 "attempting to leave " <<
comt
549 <<
" (request rejected)" << endl;
558 cerr <<
"completeSwitch: failed while "
559 "attempting to join " <<
comt
560 <<
" (timeout)" << endl;
571 if (cp.type == CtlPkt::CLIENT_JOIN_COMTREE) {
572 if (cp.mode == CtlPkt::POS_REPLY) {
575 }
else if (cp.mode == CtlPkt::NEG_REPLY) {
576 cerr <<
"completeSwitch: failed while "
577 "attempting to join " <<
comt
578 <<
" (request rejected)" << endl;
594 if (
comt == 0)
return;
600 uint32_t *pp = p.payload();
606 pp[5] = htonl((uint32_t)
speed);
621 if (
comt == 0)
return;
623 buf[0] = htonl((uint32_t) now);
624 buf[8] = htonl((uint32_t)
comt);
625 buf[9] = htonl(avType);
627 buf[1] = htonl((uint32_t)
myAdr);
628 buf[2] = htonl((uint32_t)
x);
629 buf[3] = htonl((uint32_t) y);
631 buf[5] = htonl((uint32_t)
speed);
633 buf[7] = htonl((uint32_t)
numNear);
634 }
else if (px != 0) {
636 uint32_t *pp = p.payload();
650 char *bp= (
char *) buf;
652 int n = write(
connSock, (
void *) bp, nbytes);
653 if (n < 0) fatal(
"Avatar::forwardReport: failure in write");
654 bp += n; nbytes -= n;
665 fatal(
"Avatar::send2comtCtl: no packets left to allocate");
668 CtlPkt cp(joinLeave,CtlPkt::REQUEST,
seqNum,p.payload());
674 fatal(
"Avatar::send2comtCtl: control packet packing error");
707 fatal(
"can't make connection socket nonblocking");
708 bool status;
int ndVal = 1;
709 status = setsockopt(
listenSock,IPPROTO_TCP,TCP_NODELAY,
710 (
void *) &ndVal,
sizeof(
int));
712 cerr <<
"setsockopt for no-delay failed\n";
718 int nbytes = read(
connSock, buf, 5);
720 if (errno == EAGAIN)
return 0;
721 fatal(
"Avatar::check4command: error in read call");
722 }
else if (nbytes == 0) {
726 }
else if (nbytes < 5) {
727 fatal(
"Avatar::check4command: incomplete command");
730 uint32_t param = ntohl(*((
int*) &buf[1]));
746 case 'c':
return param;
758 p.payload()[0] = htonl((uint32_t) (
nonce >> 32));
759 p.payload()[1] = htonl((uint32_t) (
nonce & 0xffffffff));
761 p.
comtree = Forest::CONNECT_COMT;
768 if (now > resendTime) {
769 if (resendCount > 3) {
ps->
free(px);
return false; }
771 resendTime += 1000000;
793 p.payload()[0] = htonl((uint32_t) (
nonce >> 32));
794 p.payload()[1] = htonl((uint32_t) (
nonce & 0xffffffff));
803 if (now > resendTime) {
804 if (resendCount > 3) {
ps->
free(px);
return false; }
806 resendTime += 1000000;
832 if (rv == -1) fatal(
"Avatar::send: failure in sendto");
840 if (px == 0)
return 0;
843 ipa_t remoteIp; ipp_t remotePort;
845 remoteIp, remotePort);
847 if (errno == EWOULDBLOCK) {
850 fatal(
"Avatar::receive: error in recvfrom call");
875 const double PI = 3.141519625;
882 int x1 =
x + (int) (dist * sin(dirRad));
883 int y1 = y + (int) (dist * cos(dirRad));
885 if (x1 <= 0 || x1 >=
GRID*worldSize-1 ||
886 y1 <= 0 || y1 >=
GRID*worldSize-1 ||
887 (prevRegion != postRegion &&
888 (
walls[postRegion]&4 ||
893 if (postRegion != prevRegion) updateVisSet();
899 bool atLeft = (prevRegion%worldSize == 0);
900 bool atRight = (prevRegion%worldSize == worldSize-1);
901 bool atBot = (prevRegion/worldSize == 0);
902 bool atTop = (prevRegion/worldSize == worldSize-1);
904 if (xd < .25*
GRID && (atLeft ||
walls[prevRegion]&1 ||
905 walls[prevRegion-1]&4)) {
910 }
else if (xd > .75*
GRID && (atRight ||
walls[prevRegion+1]&1 ||
911 walls[prevRegion+1]&4)) {
916 }
else if (yd < .25*
GRID && (atBot ||
walls[prevRegion-worldSize]&2 ||
917 walls[prevRegion-worldSize]&4)) {
922 }
else if (yd > .75*
GRID && (atTop ||
walls[prevRegion]&2 ||
923 walls[prevRegion+worldSize]&4)) {
933 if ((r = randfrac()) < 0.1) {
934 if (r < .05)
deltaDir -= 0.2 * randfrac();
940 if ((r = randfrac()) <= 0.1) {
951 x += (int) (dist * sin(dirRad));
952 y += (int) (dist * cos(dirRad));
954 if (postRegion != prevRegion) updateVisSet();
963 if (c0 > c1) {
int temp = c1; c1 = c0; c0 = temp; }
964 if (c0/worldSize == c1/worldSize)
966 else if (c0%worldSize == c1%worldSize)
968 else if (c0%worldSize > c1%worldSize) {
969 if ((
walls[c0]&3) == 3 ||
1002 int sq1 = g1-1;
int sq2 = g2-1;
1008 int x = x1; x1 = x2; x2 =
x;
1009 int y = y1; y1 = y2; y2 =
y;
1013 int lo = min(y1, y2);
int hi = max(y1, y2);
1014 for (
int y = lo; y < hi; y++) {
1015 if (
walls[x1 + y*worldSize] & 2)
return false;
1018 }
else if (y1 == y2) {
1019 for (
int x = x1+1; x <= x2; x++) {
1020 if (
walls[x + y1*worldSize] & 1)
return false;
1025 const double eps = .001;
1026 double sq1xs[] = {x1+eps, x1+(1.0-eps),x1+eps,x1+(1.0-eps)};
1027 double sq1ys[] = {y1+(1.0-eps),y1+(1.0-eps),y1+eps,y1+eps };
1028 double sq2xs[] = {x2+eps, x2+(1.0-eps),x2+eps,x2+(1.0-eps)};
1029 double sq2ys[] = {y2+(1.0-eps),y2+(1.0-eps),y2+eps,y2+eps };
1031 int miny = min(y1,y2);
int maxy = max(y1,y2);
1032 double slope = (y2-y1)/((
double) x2-x1);
1034 for (
int i = 0; i < 4; i++) {
1035 for (
int j = 0; j < 4; j++) {
1037 double ax = sq1xs[i];
double ay = sq1ys[i];
1038 double bx = sq2xs[j];
double by = sq2ys[j];
1040 for (
int x = x1; x <= x2 && canSee; x++) {
1041 int lo = miny;
int hi = maxy;
1043 lo = (x==x1 ? y1 : (int) ((x-(x1+1))*slope + y1));
1044 hi = ((x+1)-x1)*slope + (y1+1);
1045 lo = max(lo,y1); hi = min(hi,y2);
1047 lo = ((x+1)-x1)*slope + y1;
1048 hi = (x==x1 ? y1-1 : (int) ((x-(x1+1))*slope + (y1+1)));
1049 lo = max(lo,y2); hi = min(hi,y1);
1051 for (
int y = lo; y <= hi; y++) {
1052 double cx = (double) x;
1053 double cy = (double) (y+1);
1059 double dx = cx;
double dy = cy-1;
1060 if (linesIntersect(ax,ay,bx,by,cx,cy,dx,dy)) {
1061 canSee =
false;
break;
1067 double dx = cx+1;
double dy = cy;
1068 if (linesIntersect(ax,ay,bx,by,cx,cy,dx,dy)) {
1069 canSee =
false;
break;
1073 if (canSee)
return true;
1078 bool Avatar::linesIntersect(
double ax,
double ay,
double bx,
double by,
1079 double cx ,
double cy,
double dx,
double dy) {
1080 double epsilon = .001;
1083 if (abs(ax-bx) < epsilon && abs(cx-dx) < epsilon) {
1084 return abs(ax-cx) < epsilon && max(ay,by) >= min(cy,dy)
1085 && min(ay,by) <= max(cy,dy);
1088 if (abs(ax-bx) < epsilon) {
1089 double s2 = (dy-cy)/(dx-cx);
1090 double i2 = cy - s2*cx;
1091 double y = s2*ax + i2;
1092 return (y >= min(ay,by) && y <= max(ay,by) &&
1093 y >= min(cy,dy) && y <= max(cy,dy));
1095 if (abs(cx-dx) < epsilon) {
1096 double s1 = (by-ay)/(bx-ax);
1097 double i1 = ay - s1*ax;
1098 double y = s1*cx + i1;
1099 return (y >= min(ay,by) && y <= max(ay,by) &&
1100 y >= min(cy,dy) && y <= max(cy,dy));
1102 double s1 = (by-ay)/(bx-ax);
1103 double i1 = ay - s1*ax;
1104 double s2 = (dy-cy)/(dx-cx);
1105 double i2 = cy - s2*cx;
1110 if (abs(s1)+abs(s2) <= epsilon ||
1111 abs(s1-s2)/(abs(s1)+abs(s2)) < epsilon) {
1112 return (abs(i1-i2) < epsilon &&
1113 min(ax,bx) <= max(cx,dx) && max(ax,bx) >= min(cx,dx));
1116 double x = (i2-i1)/(s1-s2);
1118 return (x >= min(ax,bx) && x <= max(ax,bx) &&
1119 x >= min(cx,dx) && x <= max(cx,dx));
1122 void Avatar::subscribe(list<int>& glist) {
1123 if (
comt == 0 || glist.size() == 0)
return;
1126 uint32_t *pp = p.payload();
1129 list<int>::iterator gp;
1130 for (gp = glist.begin(); gp != glist.end(); gp++) {
1131 int g = *gp; nsub++;
1133 pp[0] = htonl((uint32_t) (
subSeqNum >> 32));
1134 pp[1] = htonl((uint32_t) (
subSeqNum & 0xffffffff));
1136 pp[2] = htonl(nsub-1); pp[nsub+2] = 0;
1144 pp[nsub+2] = htonl(-g);
1146 pp[0] = htonl((uint32_t) (
subSeqNum >> 32));
1147 pp[1] = htonl((uint32_t) (
subSeqNum & 0xffffffff));
1149 pp[2] = htonl(nsub); pp[nsub+3] = 0;
1162 if (
comt == 0 || glist.size() == 0)
return;
1165 uint32_t *pp = p.payload();
1168 list<int>::iterator gp;
1169 for (gp = glist.begin(); gp != glist.end(); gp++) {
1170 int g = *gp; nunsub++;
1172 pp[0] = htonl((uint32_t) (
subSeqNum >> 32));
1173 pp[1] = htonl((uint32_t) (
subSeqNum & 0xffffffff));
1174 pp[2] = 0; pp[3] = htonl(nunsub-1);
1182 pp[nunsub+3] = htonl(-g);
1184 pp[0] = htonl((uint32_t) (
subSeqNum >> 32));
1185 pp[1] = htonl((uint32_t) (
subSeqNum & 0xffffffff));
1187 pp[2] = 0; pp[3] = htonl(nunsub);
1200 set<int>::iterator gp;
1203 mySubs->insert(*gp); glist.push_back(*gp);
1213 set<int>::iterator gp;
1215 glist.push_back(*gp);
1228 set<int>::iterator gp;
1229 for (gp =
mySubs->begin(); gp !=
mySubs->end(); gp++) {
1235 list<int>::iterator p;
1236 for (p = glist.begin(); p != glist.end(); p++)
1243 set<int>::iterator vp;
1266 uint32_t *pp = p.payload();
1270 uint64_t avId = p.
srcAdr; avId = (avId << 32) | p.
srcAdr;
1275 int x1 = ntohl(pp[2]);
int y1 = ntohl(pp[3]);
1287 set<int>::iterator vp;
1288 int minx = min(x,x1)/
GRID;
int maxx = max(x,x1)/
GRID;
1289 int miny = min(y,y1)/
GRID;
int maxy = max(y,y1)/
GRID;
1293 if (xi < minx || xi > maxx || yi < miny || yi > maxy)
1296 int ax = xi;
int ay = yi +
GRID;
1298 if(linesIntersect(x,y,x1,y1,ax,ay,ax+GRID,ay)) {
1299 canSee =
false;
break;
1303 if(linesIntersect(x,y,x1,y1,ax,ay,ax,ay-GRID)) {
1304 canSee =
false;
break;
1342 void Avatar::updateVisSet() {