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