* add a Display name to our handlers; this will be used by DAV handlers.
[citadel.git] / webcit / marchlist.c
1 #include "webcit.h"
2 #include "webserver.h"
3
4 /*
5  * Free a session's march list
6  */
7 void free_march_list(wcsession *wcf)
8 {
9         struct march *mptr;
10
11         while (wcf->march != NULL) {
12                 mptr = wcf->march->next;
13                 free(wcf->march);
14                 wcf->march = mptr;
15         }
16
17 }
18
19
20
21 /*
22  * remove a room from the march list
23  */
24 void remove_march(const StrBuf *aaa)
25 {
26         struct march *mptr, *mptr2;
27
28         if (WC->march == NULL)
29                 return;
30
31         if (!strcasecmp(WC->march->march_name, ChrPtr(aaa))) {
32                 mptr = WC->march->next;
33                 free(WC->march);
34                 WC->march = mptr;
35                 return;
36         }
37         mptr2 = WC->march;
38         for (mptr = WC->march; mptr != NULL; mptr = mptr->next) {
39                 if (!strcasecmp(mptr->march_name, ChrPtr(aaa))) {
40                         mptr2->next = mptr->next;
41                         free(mptr);
42                         mptr = mptr2;
43                 } else {
44                         mptr2 = mptr;
45                 }
46         }
47 }
48
49
50
51 /**
52  * \brief Locate the room on the march list which we most want to go to.  
53  * Each room
54  * is measured given a "weight" of preference based on various factors.
55  * \param desired_floor the room number on the citadel server
56  * \return the roomname
57  */
58 char *pop_march(int desired_floor)
59 {
60         static char TheRoom[128];
61         int TheFloor = 0;
62         int TheOrder = 32767;
63         int TheWeight = 0;
64         int weight;
65         struct march *mptr = NULL;
66
67         strcpy(TheRoom, "_BASEROOM_");
68         if (WC->march == NULL)
69                 return (TheRoom);
70
71         for (mptr = WC->march; mptr != NULL; mptr = mptr->next) {
72                 weight = 0;
73                 if ((strcasecmp(mptr->march_name, "_BASEROOM_")))
74                         weight = weight + 10000;
75                 if (mptr->march_floor == desired_floor)
76                         weight = weight + 5000;
77
78                 weight = weight + ((128 - (mptr->march_floor)) * 128);
79                 weight = weight + (128 - (mptr->march_order));
80
81                 if (weight > TheWeight) {
82                         TheWeight = weight;
83                         strcpy(TheRoom, mptr->march_name);
84                         TheFloor = mptr->march_floor;
85                         TheOrder = mptr->march_order;
86                 }
87         }
88         return (TheRoom);
89 }
90
91
92
93 /*
94  * Goto next room having unread messages.
95  *
96  * We want to skip over rooms that the user has already been to, and take the
97  * user back to the lobby when done.  The room we end up in is placed in
98  * newroom - which is set to 0 (the lobby) initially.
99  * We start the search in the current room rather than the beginning to prevent
100  * two or more concurrent users from dragging each other back to the same room.
101  */
102 void gotonext(void)
103 {
104         char buf[256];
105         struct march *mptr = NULL;
106         struct march *mptr2 = NULL;
107         char room_name[128];
108         StrBuf *next_room;
109         int ELoop = 0;
110
111         /*
112          * First check to see if the march-mode list is already allocated.
113          * If it is, pop the first room off the list and go there.
114          */
115         if (havebstr("startmsg")) {
116                  readloop(readnew);
117                  return;
118         }
119
120         if (WC->march == NULL) {
121                 serv_puts("LKRN");
122                 serv_getln(buf, sizeof buf);
123                 if (buf[0] == '1')
124                         while (serv_getln(buf, sizeof buf), strcmp(buf, "000")) {
125                                 if (IsEmptyStr(buf)) {
126                                         if (ELoop > 10000)
127                                                 return;
128                                         if (ELoop % 100 == 0)
129                                                 sleeeeeeeeeep(1);
130                                         ELoop ++;
131                                         continue;                                       
132                                 }
133                                 extract_token(room_name, buf, 0, '|', sizeof room_name);
134                                 if (strcasecmp(room_name, ChrPtr(WC->wc_roomname))) {
135                                         mptr = (struct march *) malloc(sizeof(struct march));
136                                         mptr->next = NULL;
137                                         safestrncpy(mptr->march_name, room_name, sizeof mptr->march_name);
138                                         mptr->march_floor = extract_int(buf, 2);
139                                         mptr->march_order = extract_int(buf, 3);
140                                         if (WC->march == NULL) 
141                                                 WC->march = mptr;
142                                         else 
143                                                 mptr2->next = mptr;
144                                         mptr2 = mptr;
145                                 }
146                                 buf[0] = '\0';
147                         }
148                 /*
149                  * add _BASEROOM_ to the end of the march list, so the user will end up
150                  * in the system base room (usually the Lobby>) at the end of the loop
151                  */
152                 mptr = (struct march *) malloc(sizeof(struct march));
153                 mptr->next = NULL;
154                 mptr->march_order = 0;
155                 mptr->march_floor = 0;
156                 strcpy(mptr->march_name, "_BASEROOM_");
157                 if (WC->march == NULL) {
158                         WC->march = mptr;
159                 } else {
160                         mptr2 = WC->march;
161                         while (mptr2->next != NULL)
162                                 mptr2 = mptr2->next;
163                         mptr2->next = mptr;
164                 }
165                 /*
166                  * ...and remove the room we're currently in, so a <G>oto doesn't make us
167                  * walk around in circles
168                  */
169                 remove_march(WC->wc_roomname);
170         }
171         if (WC->march != NULL) {
172                 next_room = NewStrBufPlain(pop_march(-1), -1);/*TODO: migrate march to strbuf */
173         } else {
174                 next_room = NewStrBufPlain(HKEY("_BASEROOM_"));
175         }
176
177
178         smart_goto(next_room);
179         FreeStrBuf(&next_room);
180 }
181
182 /*
183  * un-goto the previous room
184  */
185 void ungoto(void)
186 {
187         StrBuf *Buf;
188
189         if (havebstr("startmsg")) {
190                 readloop(readnew);
191                 return;
192         }
193
194         if (!strcmp(WC->ugname, "")) {
195                 smart_goto(WC->wc_roomname);
196                 return;
197         }
198         serv_printf("GOTO %s", WC->ugname);
199         Buf = NewStrBuf();
200         StrBuf_ServGetln(Buf);
201         if (GetServerStatus(Buf, NULL) != 2) {
202                 smart_goto(WC->wc_roomname);
203                 FreeStrBuf(&Buf);
204                 return;
205         }
206         if (WC->uglsn >= 0L) {
207                 serv_printf("SLRP %ld", WC->uglsn);
208                 StrBuf_ServGetln(Buf);
209         }
210         FlushStrBuf(Buf);
211         StrBufAppendBufPlain(Buf, WC->ugname, -1, 0);
212         strcpy(WC->ugname, "");
213         smart_goto(Buf);
214         FreeStrBuf(&Buf);
215 }
216
217
218
219 void _gotonext(void) {
220         slrp_highest();
221         gotonext();
222 }
223
224
225 void dotskip(void) {
226         smart_goto(sbstr("room"));
227 }
228
229
230
231
232 void 
233 InitModule_MARCHLIST
234 (void)
235 {
236
237         WebcitAddUrlHandler(HKEY("gotonext"), "", 0, _gotonext, NEED_URL);
238         WebcitAddUrlHandler(HKEY("skip"), "", 0, gotonext, NEED_URL);
239         WebcitAddUrlHandler(HKEY("ungoto"), "", 0, ungoto, NEED_URL);
240 }