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) {
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) {
146 cerr <<
"logging in\n";
151 cerr <<
"Avatar::login: cannot open/configure socket to "
156 string s =
"Forest-login-v1\nlogin: " + uname +
157 "\npassword: " + pword +
"\nover\n";
158 cerr <<
"login string " << s << endl;
162 if (!buf.readLine(s0) || s0 !=
"success" ||
163 !buf.readLine(s1) || s1 !=
"over") {
168 s =
"newSession\nover\n";
173 if (!buf.readAlphas(s0) || s0 !=
"yourAddress" || !buf.verify(
':') ||
174 !buf.readForestAddress(s1) || !buf.nextLine())
181 if (!buf.readAlphas(s0) || s0 !=
"yourRouter" || !buf.verify(
':') ||
182 !buf.verify(
'(') || !buf.readIpAddress(s1) || !buf.verify(
',') ||
183 !buf.readInt(port) || !buf.verify(
',') ||
184 !buf.readForestAddress(s2) || !buf.verify(
')') || !buf.nextLine())
192 if (!buf.readAlphas(s0) || s0 !=
"comtCtlAddress" || !buf.verify(
':') ||
193 !buf.readForestAddress(s1) || !buf.nextLine())
199 if (!buf.readAlphas(s0) || s0 !=
"connectNonce" || !buf.verify(
':') ||
200 !buf.readInt(
nonce) || !buf.nextLine())
202 if (!buf.readLine(s0) || (s0 !=
"over" && s0 !=
"overAndOut"))
212 cout <<
"nonce=" <<
nonce << endl;
222 ifstream ifs(wallsFile);
224 cerr <<
"setupWalls: cannot open walls file\n";
228 bool horizRow =
true;
237 }
catch(exception& e) {
238 cerr <<
"setupWalls: could not allocate space "
239 "for walls array (worldSize="
244 }
else if ((
int) line.size()/2 !=
worldSize) {
245 cerr <<
"setupWalls: format error, all lines must have "
249 for(
int xx = 0; xx < 2*
worldSize; xx++) {
250 int pos = y * worldSize + xx/2;
252 if (!(xx&1))
continue;
253 if (line[xx] ==
'-')
walls[pos] |= 2;
257 if (line[xx] ==
'x')
walls[pos] |= 4;
258 }
else if (line[xx] ==
'|')
walls[pos] |= 1;
260 horizRow = !horizRow;
273 int x1 = (g1-1)%worldSize;
int y1 = (g1-1)/worldSize;
281 prevVisVec[0] =
true;
282 int dlimit = min(worldSize,
MAX_VIS);
283 for (
int d = 1; d <= dlimit; d++) {
285 for (
int x2 = x1; x2 <= min(x1+d,worldSize-1); x2++) {
286 int y2 = d + y1 - (x2 - x1);
287 if (y2 >= worldSize)
continue;
290 if ((x1==x2 && !prevVisVec[dx]) ||
291 (x1!=x2 && y1==y2 && !prevVisVec[dx-1]) ||
292 (x1!=x2 && y1!=y2 && !prevVisVec[dx-1] &&
305 for (
int x2 = x1; x2 <= min(x1+d,worldSize-1); x2++) {
306 prevVisVec[x2-x1] = visVec[x2-x1];
310 prevVisVec[0] =
true;
311 for (
int d = 1; d <= dlimit; d++) {
313 for (
int x2 = x1; x2 >= max(x1-d,0); x2--) {
315 int y2 = d + y1 - dx;
316 if (y2 >= worldSize)
continue;
318 if ((x1==x2 && !prevVisVec[dx]) ||
319 (x1!=x2 && y1==y2 && !prevVisVec[dx-1]) ||
320 (x1!=x2 && y1!=y2 && !prevVisVec[dx-1] &&
332 for (
int x2 = x1; x2 >= max(x1-d,0); x2--) {
334 prevVisVec[dx] = visVec[dx];
338 prevVisVec[0] =
true;
339 for (
int d = 1; d <= dlimit; d++) {
341 for (
int x2 = x1; x2 >= max(x1-d,0); x2--) {
343 int y2 = (y1 - d) + dx;
344 if (y2 < 0)
continue;
346 if ((x1==x2 && !prevVisVec[dx]) ||
347 (x1!=x2 && y1==y2 && !prevVisVec[dx-1]) ||
348 (x1!=x2 && y1!=y2 && !prevVisVec[dx-1] &&
360 for (
int x2 = x1; x2 >= max(x1-d,0); x2--) {
362 prevVisVec[dx] = visVec[dx];
366 prevVisVec[0] =
true;
367 for (
int d = 1; d <= dlimit; d++) {
369 for (
int x2 = x1; x2 <= min(x1+d,worldSize-1); x2++) {
371 int y2 = (y1 - d) + dx;
372 if (y2 < 0)
continue;
374 if ((x1==x2 && !prevVisVec[dx]) ||
375 (x1!=x2 && y1==y2 && !prevVisVec[dx-1]) ||
376 (x1!=x2 && y1!=y2 && !prevVisVec[dx-1] &&
388 for (
int x2 = x1; x2 <= min(x1+d,worldSize-1); x2++) {
390 prevVisVec[dx] = visVec[dx];
393 delete [] visVec;
delete [] prevVisVec;
410 uint32_t lastComtSwitch;
413 uint32_t comtSwitchTime = now+1;
416 bool waiting4switch =
false;
417 while (finishTime == 0 || now <= finishTime) {
425 if (newComt != 0 && newComt !=
comt) {
427 waiting4switch =
true;
432 while ((px =
receive()) != 0) {
435 if (waiting4switch) {
452 key = (key << 32) | p.
srcAdr;
461 if (!waiting4switch) {
469 }
else if (
comt == 0 ||
470 now-comtSwitchTime < ((
unsigned) 1)<<31) {
472 lastComtSwitch = now;
473 comt_t newComt = randint(firstComt, lastComt);
474 if (
comt != newComt) {
476 waiting4switch =
true;
478 comtSwitchTime = now + randint(10,30)*1000000;
485 useconds_t delay = nextTime - now;
486 if (delay < ((uint32_t) 1) << 31) usleep(delay);
533 cerr <<
"completeSwitch: failed while "
534 "attempting to leave " <<
comt
535 <<
" (timeout)" << endl;
546 if (cp.type == CtlPkt::CLIENT_LEAVE_COMTREE) {
547 if (cp.mode == CtlPkt::POS_REPLY) {
553 }
else if (cp.mode == CtlPkt::NEG_REPLY) {
554 cerr <<
"completeSwitch: failed while "
555 "attempting to leave " <<
comt
556 <<
" (request rejected)" << endl;
565 cerr <<
"completeSwitch: failed while "
566 "attempting to join " <<
comt
567 <<
" (timeout)" << endl;
578 if (cp.type == CtlPkt::CLIENT_JOIN_COMTREE) {
579 if (cp.mode == CtlPkt::POS_REPLY) {
582 }
else if (cp.mode == CtlPkt::NEG_REPLY) {
583 cerr <<
"completeSwitch: failed while "
584 "attempting to join " <<
comt
585 <<
" (request rejected)" << endl;
601 if (
comt == 0)
return;
607 uint32_t *pp = p.payload();
613 pp[5] = htonl((uint32_t)
speed);
628 if (
comt == 0)
return;
630 buf[0] = htonl((uint32_t) now);
631 buf[8] = htonl((uint32_t)
comt);
632 buf[9] = htonl(avType);
634 buf[1] = htonl((uint32_t)
myAdr);
635 buf[2] = htonl((uint32_t)
x);
636 buf[3] = htonl((uint32_t) y);
638 buf[5] = htonl((uint32_t)
speed);
640 buf[7] = htonl((uint32_t)
numNear);
641 }
else if (px != 0) {
643 uint32_t *pp = p.payload();
657 char *bp= (
char *) buf;
659 int n = write(
connSock, (
void *) bp, nbytes);
660 if (n < 0) fatal(
"Avatar::forwardReport: failure in write");
661 bp += n; nbytes -= n;
672 fatal(
"Avatar::send2comtCtl: no packets left to allocate");
675 CtlPkt cp(joinLeave,CtlPkt::REQUEST,
seqNum,p.payload());
681 fatal(
"Avatar::send2comtCtl: control packet packing error");
714 fatal(
"can't make connection socket nonblocking");
715 bool status;
int ndVal = 1;
716 status = setsockopt(
listenSock,IPPROTO_TCP,TCP_NODELAY,
717 (
void *) &ndVal,
sizeof(
int));
719 cerr <<
"setsockopt for no-delay failed\n";
725 int nbytes = read(
connSock, buf, 5);
727 if (errno == EAGAIN)
return 0;
728 fatal(
"Avatar::check4command: error in read call");
729 }
else if (nbytes == 0) {
733 }
else if (nbytes < 5) {
734 fatal(
"Avatar::check4command: incomplete command");
737 uint32_t param = ntohl(*((
int*) &buf[1]));
753 case 'c':
return param;
765 p.payload()[0] = htonl((uint32_t) (
nonce >> 32));
766 p.payload()[1] = htonl((uint32_t) (
nonce & 0xffffffff));
768 p.
comtree = Forest::CONNECT_COMT;
775 if (now > resendTime) {
776 if (resendCount > 3) {
ps->
free(px);
return false; }
778 resendTime += 1000000;
782 if (rx == 0) { usleep(100000);
continue; }
797 p.payload()[0] = htonl((uint32_t) (
nonce >> 32));
798 p.payload()[1] = htonl((uint32_t) (
nonce & 0xffffffff));
807 if (now > resendTime) {
808 if (resendCount > 3) {
ps->
free(px);
return false; }
810 resendTime += 1000000;
814 if (rx == 0) { usleep(100000);
continue; }
833 if (rv == -1) fatal(
"Avatar::send: failure in sendto");
841 if (px == 0)
return 0;
844 ipa_t remoteIp; ipp_t remotePort;
846 remoteIp, remotePort);
848 if (errno == EWOULDBLOCK) {
851 fatal(
"Avatar::receive: error in recvfrom call");
876 const double PI = 3.141519625;
883 int x1 =
x + (int) (dist * sin(dirRad));
884 int y1 = y + (int) (dist * cos(dirRad));
886 if (x1 <= 0 || x1 >=
GRID*worldSize-1 ||
887 y1 <= 0 || y1 >=
GRID*worldSize-1 ||
888 (prevRegion != postRegion &&
889 (
walls[postRegion]&4 ||
894 if (postRegion != prevRegion) updateVisSet();
900 bool atLeft = (prevRegion%worldSize == 0);
901 bool atRight = (prevRegion%worldSize == worldSize-1);
902 bool atBot = (prevRegion/worldSize == 0);
903 bool atTop = (prevRegion/worldSize == worldSize-1);
905 if (xd < .25*
GRID && (atLeft ||
walls[prevRegion]&1 ||
906 walls[prevRegion-1]&4)) {
911 }
else if (xd > .75*
GRID && (atRight ||
walls[prevRegion+1]&1 ||
912 walls[prevRegion+1]&4)) {
917 }
else if (yd < .25*
GRID && (atBot ||
walls[prevRegion-worldSize]&2 ||
918 walls[prevRegion-worldSize]&4)) {
923 }
else if (yd > .75*
GRID && (atTop ||
walls[prevRegion]&2 ||
924 walls[prevRegion+worldSize]&4)) {
934 if ((r = randfrac()) < 0.1) {
935 if (r < .05)
deltaDir -= 0.2 * randfrac();
941 if ((r = randfrac()) <= 0.1) {
952 x += (int) (dist * sin(dirRad));
953 y += (int) (dist * cos(dirRad));
955 if (postRegion != prevRegion) updateVisSet();
964 if (c0 > c1) {
int temp = c1; c1 = c0; c0 = temp; }
965 if (c0/worldSize == c1/worldSize)
967 else if (c0%worldSize == c1%worldSize)
969 else if (c0%worldSize > c1%worldSize) {
970 if ((
walls[c0]&3) == 3 ||
1003 int sq1 = g1-1;
int sq2 = g2-1;
1009 int x = x1; x1 = x2; x2 =
x;
1010 int y = y1; y1 = y2; y2 =
y;
1014 int lo = min(y1, y2);
int hi = max(y1, y2);
1015 for (
int y = lo; y < hi; y++) {
1016 if (
walls[x1 + y*worldSize] & 2)
return false;
1019 }
else if (y1 == y2) {
1020 for (
int x = x1+1; x <= x2; x++) {
1021 if (
walls[x + y1*worldSize] & 1)
return false;
1026 const double eps = .001;
1027 double sq1xs[] = {x1+eps, x1+(1.0-eps),x1+eps,x1+(1.0-eps)};
1028 double sq1ys[] = {y1+(1.0-eps),y1+(1.0-eps),y1+eps,y1+eps };
1029 double sq2xs[] = {x2+eps, x2+(1.0-eps),x2+eps,x2+(1.0-eps)};
1030 double sq2ys[] = {y2+(1.0-eps),y2+(1.0-eps),y2+eps,y2+eps };
1032 int miny = min(y1,y2);
int maxy = max(y1,y2);
1033 double slope = (y2-y1)/((
double) x2-x1);
1035 for (
int i = 0; i < 4; i++) {
1036 for (
int j = 0; j < 4; j++) {
1038 double ax = sq1xs[i];
double ay = sq1ys[i];
1039 double bx = sq2xs[j];
double by = sq2ys[j];
1041 for (
int x = x1; x <= x2 && canSee; x++) {
1042 int lo = miny;
int hi = maxy;
1044 lo = (x==x1 ? y1 : (int) ((x-(x1+1))*slope + y1));
1045 hi = ((x+1)-x1)*slope + (y1+1);
1046 lo = max(lo,y1); hi = min(hi,y2);
1048 lo = ((x+1)-x1)*slope + y1;
1049 hi = (x==x1 ? y1-1 : (int) ((x-(x1+1))*slope + (y1+1)));
1050 lo = max(lo,y2); hi = min(hi,y1);
1052 for (
int y = lo; y <= hi; y++) {
1053 double cx = (double) x;
1054 double cy = (double) (y+1);
1060 double dx = cx;
double dy = cy-1;
1061 if (linesIntersect(ax,ay,bx,by,cx,cy,dx,dy)) {
1062 canSee =
false;
break;
1068 double dx = cx+1;
double dy = cy;
1069 if (linesIntersect(ax,ay,bx,by,cx,cy,dx,dy)) {
1070 canSee =
false;
break;
1074 if (canSee)
return true;
1079 bool Avatar::linesIntersect(
double ax,
double ay,
double bx,
double by,
1080 double cx ,
double cy,
double dx,
double dy) {
1081 double epsilon = .001;
1084 if (abs(ax-bx) < epsilon && abs(cx-dx) < epsilon) {
1085 return abs(ax-cx) < epsilon && max(ay,by) >= min(cy,dy)
1086 && min(ay,by) <= max(cy,dy);
1089 if (abs(ax-bx) < epsilon) {
1090 double s2 = (dy-cy)/(dx-cx);
1091 double i2 = cy - s2*cx;
1092 double y = s2*ax + i2;
1093 return (y >= min(ay,by) && y <= max(ay,by) &&
1094 y >= min(cy,dy) && y <= max(cy,dy));
1096 if (abs(cx-dx) < epsilon) {
1097 double s1 = (by-ay)/(bx-ax);
1098 double i1 = ay - s1*ax;
1099 double y = s1*cx + i1;
1100 return (y >= min(ay,by) && y <= max(ay,by) &&
1101 y >= min(cy,dy) && y <= max(cy,dy));
1103 double s1 = (by-ay)/(bx-ax);
1104 double i1 = ay - s1*ax;
1105 double s2 = (dy-cy)/(dx-cx);
1106 double i2 = cy - s2*cx;
1111 if (abs(s1)+abs(s2) <= epsilon ||
1112 abs(s1-s2)/(abs(s1)+abs(s2)) < epsilon) {
1113 return (abs(i1-i2) < epsilon &&
1114 min(ax,bx) <= max(cx,dx) && max(ax,bx) >= min(cx,dx));
1117 double x = (i2-i1)/(s1-s2);
1119 return (x >= min(ax,bx) && x <= max(ax,bx) &&
1120 x >= min(cx,dx) && x <= max(cx,dx));
1123 void Avatar::subscribe(list<int>& glist) {
1124 if (
comt == 0 || glist.size() == 0)
return;
1127 uint32_t *pp = p.payload();
1130 list<int>::iterator gp;
1131 for (gp = glist.begin(); gp != glist.end(); gp++) {
1132 int g = *gp; nsub++;
1134 pp[0] = htonl((uint32_t) (
subSeqNum >> 32));
1135 pp[1] = htonl((uint32_t) (
subSeqNum & 0xffffffff));
1137 pp[2] = htonl(nsub-1); pp[nsub+2] = 0;
1145 pp[nsub+2] = htonl(-g);
1147 pp[0] = htonl((uint32_t) (
subSeqNum >> 32));
1148 pp[1] = htonl((uint32_t) (
subSeqNum & 0xffffffff));
1150 pp[2] = htonl(nsub); pp[nsub+3] = 0;
1163 if (
comt == 0 || glist.size() == 0)
return;
1166 uint32_t *pp = p.payload();
1169 list<int>::iterator gp;
1170 for (gp = glist.begin(); gp != glist.end(); gp++) {
1171 int g = *gp; nunsub++;
1173 pp[0] = htonl((uint32_t) (
subSeqNum >> 32));
1174 pp[1] = htonl((uint32_t) (
subSeqNum & 0xffffffff));
1175 pp[2] = 0; pp[3] = htonl(nunsub-1);
1183 pp[nunsub+3] = htonl(-g);
1185 pp[0] = htonl((uint32_t) (
subSeqNum >> 32));
1186 pp[1] = htonl((uint32_t) (
subSeqNum & 0xffffffff));
1188 pp[2] = 0; pp[3] = htonl(nunsub);
1201 set<int>::iterator gp;
1204 mySubs->insert(*gp); glist.push_back(*gp);
1214 set<int>::iterator gp;
1216 glist.push_back(*gp);
1229 set<int>::iterator gp;
1230 for (gp =
mySubs->begin(); gp !=
mySubs->end(); gp++) {
1236 list<int>::iterator p;
1237 for (p = glist.begin(); p != glist.end(); p++)
1244 set<int>::iterator vp;
1267 uint32_t *pp = p.payload();
1271 uint64_t avId = p.
srcAdr; avId = (avId << 32) | p.
srcAdr;
1276 int x1 = ntohl(pp[2]);
int y1 = ntohl(pp[3]);
1288 set<int>::iterator vp;
1289 int minx = min(x,x1)/
GRID;
int maxx = max(x,x1)/
GRID;
1290 int miny = min(y,y1)/
GRID;
int maxy = max(y,y1)/
GRID;
1294 if (xi < minx || xi > maxx || yi < miny || yi > maxy)
1297 int ax = xi;
int ay = yi +
GRID;
1299 if(linesIntersect(x,y,x1,y1,ax,ay,ax+GRID,ay)) {
1300 canSee =
false;
break;
1304 if(linesIntersect(x,y,x1,y1,ax,ay,ax,ay-GRID)) {
1305 canSee =
false;
break;
1343 void Avatar::updateVisSet() {