MG Mud User | 88f1247 | 2016-06-24 23:31:02 +0200 | [diff] [blame] | 1 | // MorgenGrauen MUDlib |
| 2 | // |
| 3 | // channel.c -- channel client |
| 4 | // |
| 5 | // $Id: channel.c 9404 2015-12-13 00:21:44Z Zesstra $ |
| 6 | #pragma strong_types |
| 7 | #pragma save_types |
| 8 | #pragma range_check |
| 9 | #pragma no_clone |
MG Mud User | 88f1247 | 2016-06-24 23:31:02 +0200 | [diff] [blame] | 10 | |
| 11 | #define NEED_PROTOTYPES |
| 12 | #include <util.h> |
| 13 | #include <thing/properties.h> |
| 14 | #include <living/comm.h> |
| 15 | #include <player.h> |
| 16 | #include <player/comm.h> |
| 17 | #include <daemon.h> |
| 18 | #include <player/gmcp.h> |
| 19 | #undef NEED_PROTOTYPES |
| 20 | |
| 21 | #include <wizlevels.h> |
| 22 | #include <defines.h> |
| 23 | #include <properties.h> |
| 24 | #include <sys_debug.h> |
| 25 | #include <regexp.h> |
| 26 | |
MG Mud User | 88f1247 | 2016-06-24 23:31:02 +0200 | [diff] [blame] | 27 | #define P_CHANNEL_SHORT "short_channels" |
| 28 | |
| 29 | #define CHANNELCMDS "[#@%$&()<>a-zA-Z0-9\\-]" |
| 30 | |
Arathorn | 78c0837 | 2019-12-11 20:14:23 +0100 | [diff] [blame] | 31 | #define DEFAULT_CHANNELS ({"Abenteuer", "Anfaenger", "Grats", "Tod", "ZT"}) |
MG Mud User | 88f1247 | 2016-06-24 23:31:02 +0200 | [diff] [blame] | 32 | #define DEFAULT_SHORTCUTS \ |
| 33 | ([ \ |
| 34 | "b":"Abenteuer", \ |
| 35 | "a":"Allgemein", \ |
| 36 | "B":"Beileid", \ |
| 37 | "q":"D-chat", \ |
| 38 | "G":"Grats", \ |
| 39 | "M":"Moerder", \ |
| 40 | "h":"Seher", \ |
| 41 | "T":"Tod", \ |
| 42 | ]) |
| 43 | |
| 44 | #define WIZARD_SHORTCUTS \ |
| 45 | ([ \ |
| 46 | "P":"D-code", \ |
| 47 | "D":"Debug", \ |
| 48 | "O":"Intercode", \ |
| 49 | "I":"Intermud", \ |
| 50 | "m":"Magier", \ |
| 51 | ]) |
| 52 | |
Arathorn | 78c0837 | 2019-12-11 20:14:23 +0100 | [diff] [blame] | 53 | // TODO: <shortcut> wird eigentlich nur in getChannel() sinnvoll verwendet |
| 54 | // Koennte man an sich komplett einsparen und dort wie ueberall sonst auch |
| 55 | // einfach nur mit P_CHANNEL_SHORT arbeiten. |
MG Mud User | 88f1247 | 2016-06-24 23:31:02 +0200 | [diff] [blame] | 56 | private nosave mapping shortcut; |
| 57 | private nosave int c_status; |
| 58 | |
| 59 | void create() |
| 60 | { |
| 61 | Set(P_CHANNELS, SAVE, F_MODE); |
| 62 | Set(P_CHANNELS, DEFAULT_CHANNELS); |
| 63 | Set(P_SWAP_CHANNELS, SAVE, F_MODE); |
| 64 | Set(P_STD_CHANNEL, "Allgemein"); |
| 65 | Set(P_STD_CHANNEL, SAVE, F_MODE); |
| 66 | Set(P_CHANNEL_SHORT, SAVE, F_MODE); |
| 67 | Set(P_CHANNEL_SHORT, DEFAULT_SHORTCUTS |
Arathorn | 78c0837 | 2019-12-11 20:14:23 +0100 | [diff] [blame] | 68 | + (IS_LEARNER(ME) ? WIZARD_SHORTCUTS : ([]))); |
MG Mud User | 88f1247 | 2016-06-24 23:31:02 +0200 | [diff] [blame] | 69 | } |
| 70 | |
Arathorn | 0076469 | 2019-11-27 22:09:31 +0100 | [diff] [blame] | 71 | static <int|string>** _query_localcmds() |
MG Mud User | 88f1247 | 2016-06-24 23:31:02 +0200 | [diff] [blame] | 72 | { |
| 73 | return ({({"-","ChannelParser", 1, 0}), |
| 74 | ({"ebene", "ChannelAdmin", 0, 0}), |
| 75 | ({"ebenen", "ChannelAdmin", 1, 0}), |
| 76 | }); |
| 77 | } |
| 78 | |
Arathorn | 0076469 | 2019-11-27 22:09:31 +0100 | [diff] [blame] | 79 | string* RegisterChannels() |
MG Mud User | 88f1247 | 2016-06-24 23:31:02 +0200 | [diff] [blame] | 80 | { |
Arathorn | 85de760 | 2019-11-28 23:04:03 +0100 | [diff] [blame] | 81 | if (extern_call() && |
| 82 | previous_object() != find_object(CHMASTER)) |
Zesstra | f1137e8 | 2019-11-27 23:37:30 +0100 | [diff] [blame] | 83 | return 0; |
| 84 | |
MG Mud User | 88f1247 | 2016-06-24 23:31:02 +0200 | [diff] [blame] | 85 | c_status = 0; |
| 86 | shortcut = QueryProp(P_CHANNEL_SHORT); |
Arathorn | 85de760 | 2019-11-28 23:04:03 +0100 | [diff] [blame] | 87 | SetProp(P_CHANNELS, map(QueryProp(P_CHANNELS) || ({}), #'lower_case)); |
| 88 | |
| 89 | closure cl = symbol_function("join", CHMASTER); |
| 90 | string* err; |
| 91 | if (closurep(cl)) |
| 92 | { |
Arathorn | 78c0837 | 2019-12-11 20:14:23 +0100 | [diff] [blame] | 93 | err = filter(QueryProp(P_CHANNELS), cl, ME); |
MG Mud User | 88f1247 | 2016-06-24 23:31:02 +0200 | [diff] [blame] | 94 | } |
Arathorn | 85de760 | 2019-11-28 23:04:03 +0100 | [diff] [blame] | 95 | if (QueryProp(P_LEVEL) < 5) |
| 96 | return err; |
| 97 | |
| 98 | // CHMASTER->new() gibt bei Erfolg 0 zurueck, d.h. es bleiben |
| 99 | // alle Elemente erhalten, deren Channel nicht erstellt werden konnten. |
| 100 | // Die werden an die Aufrufer zurueckgegeben. |
Arathorn | 78c0837 | 2019-12-11 20:14:23 +0100 | [diff] [blame] | 101 | return filter(err, "new", CHMASTER, ME); |
MG Mud User | 88f1247 | 2016-06-24 23:31:02 +0200 | [diff] [blame] | 102 | } |
| 103 | |
Arathorn | 0076469 | 2019-11-27 22:09:31 +0100 | [diff] [blame] | 104 | string* RemoveChannels() |
MG Mud User | 88f1247 | 2016-06-24 23:31:02 +0200 | [diff] [blame] | 105 | { |
Arathorn | 85de760 | 2019-11-28 23:04:03 +0100 | [diff] [blame] | 106 | if (extern_call() && |
| 107 | previous_object() != find_object(CHMASTER)) |
Zesstra | f1137e8 | 2019-11-27 23:37:30 +0100 | [diff] [blame] | 108 | return 0; |
| 109 | |
Arathorn | 85de760 | 2019-11-28 23:04:03 +0100 | [diff] [blame] | 110 | string* err = ({}); |
| 111 | |
| 112 | if (!c_status) |
| 113 | c_status = 1; |
| 114 | else |
| 115 | return err; |
| 116 | |
| 117 | closure cl = symbol_function("leave", CHMASTER); |
| 118 | if (closurep(cl)) |
| 119 | { |
Arathorn | 78c0837 | 2019-12-11 20:14:23 +0100 | [diff] [blame] | 120 | err = filter(QueryProp(P_CHANNELS), cl, ME); |
Arathorn | 85de760 | 2019-11-28 23:04:03 +0100 | [diff] [blame] | 121 | SetProp(P_CHANNELS, QueryProp(P_CHANNELS) - err); |
MG Mud User | 88f1247 | 2016-06-24 23:31:02 +0200 | [diff] [blame] | 122 | } |
| 123 | return err; |
| 124 | } |
| 125 | |
Arathorn | 78c0837 | 2019-12-11 20:14:23 +0100 | [diff] [blame] | 126 | varargs private string getName(string|object|closure who, int fall) { |
| 127 | // Objekt zur Closure raussuchen. <o> ist danach entweder jenes Objekt, |
| 128 | // oder aber <who> selbst, das Objekt oder String sein kann. |
| 129 | // |
| 130 | // query_closure_object() KANN auch 0 oder -1 zurueckgeben. In beiden |
| 131 | // Faellen fuehrt das hier zu einem Laufzeit-Typfehler, weil ein Integer |
| 132 | // bzw. die urspruengliche Closure zugewiesen wird. Diesen Fall abzufangen |
| 133 | // und separat zu behandeln, hilft nicht, weil es auch keine alternative |
| 134 | // Moeglichkeit gibt, <who> in verwendbare Daten umzuwandeln, denn das ist |
| 135 | // ja offenbar eine kaputte Closure. Dieser Fall ist ausserdem anscheinend |
| 136 | // so exotisch, dass wir vorerst auf Absicherungen mittels catch() |
| 137 | // verzichten. |
| 138 | string|object o = closurep(who) ? query_closure_object(who) : who; |
| 139 | |
| 140 | // Ist es ein String, pruefen wir, ob es vielleicht ein Objektname ist, |
| 141 | // indem wir es in ein Objekt umzuwandeln versuchen. Schlaegt das fehl, |
| 142 | // schreiben wir <who> wieder zurueck, so dass <o> wieder der urspruengliche |
| 143 | // String ist. |
| 144 | if (stringp(o) && sizeof(o)) |
| 145 | o = find_object(o) || who; |
Arathorn | 85de760 | 2019-11-28 23:04:03 +0100 | [diff] [blame] | 146 | |
MG Mud User | 88f1247 | 2016-06-24 23:31:02 +0200 | [diff] [blame] | 147 | // Objekte |
Arathorn | 85de760 | 2019-11-28 23:04:03 +0100 | [diff] [blame] | 148 | if (objectp(o)) |
| 149 | { |
MG Mud User | 88f1247 | 2016-06-24 23:31:02 +0200 | [diff] [blame] | 150 | // Magier sehen unsichtbare nicht nur als "Jemand" |
Arathorn | 78c0837 | 2019-12-11 20:14:23 +0100 | [diff] [blame] | 151 | if (o->QueryProp(P_INVIS) && IS_LEARNING(ME)) |
MG Mud User | 88f1247 | 2016-06-24 23:31:02 +0200 | [diff] [blame] | 152 | return "("+capitalize(getuid(o))+")"; |
| 153 | // Froesche mit Namen versorgen. |
| 154 | if (o->QueryProp(P_FROG)) |
| 155 | return "Frosch "+capitalize(getuid(o)); |
| 156 | // Default (Unsichtbare als "Jemand" (s. Name())) |
| 157 | return o->Name(fall, 2)||"<Unbekannt>"; |
| 158 | } |
| 159 | // Strings |
Arathorn | 85de760 | 2019-11-28 23:04:03 +0100 | [diff] [blame] | 160 | else if (stringp(o) && sizeof(o)) |
| 161 | { |
| 162 | if (o[0] == '/') |
| 163 | { |
MG Mud User | 88f1247 | 2016-06-24 23:31:02 +0200 | [diff] [blame] | 164 | // unsichtbare Objekte... |
| 165 | int p = strstr(o, "$"); |
Arathorn | 85de760 | 2019-11-28 23:04:03 +0100 | [diff] [blame] | 166 | if (p != -1) |
| 167 | { |
| 168 | // Magier im Magiermodus kriegen den Realnamen, andere nicht. |
Arathorn | 78c0837 | 2019-12-11 20:14:23 +0100 | [diff] [blame] | 169 | if (IS_LEARNING(ME)) |
Arathorn | 85de760 | 2019-11-28 23:04:03 +0100 | [diff] [blame] | 170 | return o[1..p-1]; |
| 171 | else |
| 172 | return o[p+1..]; |
MG Mud User | 88f1247 | 2016-06-24 23:31:02 +0200 | [diff] [blame] | 173 | } |
Arathorn | 85de760 | 2019-11-28 23:04:03 +0100 | [diff] [blame] | 174 | else // doch nicht unsichtbar |
| 175 | return (fall == WESSEN ? o+"s" : o); |
MG Mud User | 88f1247 | 2016-06-24 23:31:02 +0200 | [diff] [blame] | 176 | } |
| 177 | else |
| 178 | // nicht unsichtbar |
| 179 | return (fall == WESSEN ? o+"s" : o); |
| 180 | } |
| 181 | // Fall-through |
| 182 | return "<Unbekannt>"; |
| 183 | } |
| 184 | |
Arathorn | 69d6ddd | 2019-11-25 21:06:34 +0100 | [diff] [blame] | 185 | // <nonint> unterdrueckt die Ausgabe an den Spieler und liefert den Text |
Arathorn | 85de760 | 2019-11-28 23:04:03 +0100 | [diff] [blame] | 186 | // zurueck. Wird nur fuer die Ebenenhistory benutzt. |
Arathorn | 69d6ddd | 2019-11-25 21:06:34 +0100 | [diff] [blame] | 187 | string ChannelMessage(<string|object|int>* msg, int nonint) |
MG Mud User | 88f1247 | 2016-06-24 23:31:02 +0200 | [diff] [blame] | 188 | { |
| 189 | string channel_message; |
Arathorn | 85de760 | 2019-11-28 23:04:03 +0100 | [diff] [blame] | 190 | string channel = msg[0]; |
Arathorn | 69d6ddd | 2019-11-25 21:06:34 +0100 | [diff] [blame] | 191 | |
| 192 | // Wenn eine Ebenenmeldung ausgegeben werden soll, ist msg[1] ein Objekt, |
| 193 | // im Fall der History aber ein String. Daher wird <sender> als Union |
| 194 | // deklariert. Das ist unproblematisch, weil die beiden Datentypen |
| 195 | // komplett getrennte Wege nehmen: ein Objekt wird an ReceiveMsg() |
| 196 | // durchgereicht (Ebenenmeldung). Ein String wird direkt in die Meldung |
| 197 | // (History) eingebaut, diese an den ChannelParser() zurueckgegeben, der |
| 198 | // sie via More() ausgibt. |
Arathorn | 85de760 | 2019-11-28 23:04:03 +0100 | [diff] [blame] | 199 | string|object sender = msg[1]; |
| 200 | string message = msg[2]; |
MG Mud User | 88f1247 | 2016-06-24 23:31:02 +0200 | [diff] [blame] | 201 | int msg_type = msg[3]; |
| 202 | |
Arathorn | 85de760 | 2019-11-28 23:04:03 +0100 | [diff] [blame] | 203 | if (previous_object() != find_object(CHMASTER) && |
| 204 | previous_object() != ME ) |
| 205 | return 0; |
MG Mud User | 88f1247 | 2016-06-24 23:31:02 +0200 | [diff] [blame] | 206 | |
| 207 | string sender_name = getName(sender, msg_type == MSG_GEMOTE ? WESSEN : WER); |
Arathorn | 85de760 | 2019-11-28 23:04:03 +0100 | [diff] [blame] | 208 | int prepend_indent_flag = |
| 209 | QueryProp(P_MESSAGE_PREPEND) ? BS_PREPEND_INDENT : 0; |
| 210 | |
| 211 | switch (msg_type) |
| 212 | { |
| 213 | case MSG_EMPTY: |
| 214 | channel_message= message+"\n"; |
| 215 | break; |
| 216 | case MSG_GEMOTE: |
| 217 | case MSG_EMOTE: |
| 218 | channel_message = break_string(sender_name + " "+ message+"]", 78, |
| 219 | sprintf("[%s:", channel), |
| 220 | BS_INDENT_ONCE|prepend_indent_flag); |
| 221 | break; |
| 222 | case MSG_SAY: |
| 223 | default: |
Arathorn | 78c0837 | 2019-12-11 20:14:23 +0100 | [diff] [blame] | 224 | string presay = sprintf("[%s:%s] ", channel, sender_name); |
Arathorn | 85de760 | 2019-11-28 23:04:03 +0100 | [diff] [blame] | 225 | channel_message = break_string(message, max(78,sizeof(presay)+10), |
| 226 | presay, prepend_indent_flag); |
| 227 | break; |
MG Mud User | 88f1247 | 2016-06-24 23:31:02 +0200 | [diff] [blame] | 228 | } |
Arathorn | 85de760 | 2019-11-28 23:04:03 +0100 | [diff] [blame] | 229 | |
| 230 | if (nonint) |
MG Mud User | 88f1247 | 2016-06-24 23:31:02 +0200 | [diff] [blame] | 231 | return channel_message; |
| 232 | |
| 233 | // Wenn GMCP sich um Uebertragung der Nachricht kuemmert, wird ReceiveMsg() |
Zesstra | 7ccec73 | 2019-01-06 22:10:09 +0100 | [diff] [blame] | 234 | // nicht mehr aufgerufen. getName leider nochmal aufrufen, weil GMCP den |
| 235 | // Namen im Nominativ braucht. |
| 236 | if (msg_type == MSG_GEMOTE) |
| 237 | sender_name = getName(sender, WER); |
MG Mud User | 88f1247 | 2016-06-24 23:31:02 +0200 | [diff] [blame] | 238 | if (GMCP_Channel(channel_message, channel, sender_name) != 1) |
| 239 | { |
| 240 | // Der Ebenenname muss in Kleinbuchstaben uebergeben werden, damit die |
| 241 | // Ignorierepruefung funktioniert. Die ignorierestrings sind naemlich alle |
| 242 | // kleingeschrieben. |
Arathorn | 85de760 | 2019-11-28 23:04:03 +0100 | [diff] [blame] | 243 | ReceiveMsg(channel_message, |
MG Mud User | 88f1247 | 2016-06-24 23:31:02 +0200 | [diff] [blame] | 244 | MT_COMM|MT_FAR|MSG_DONT_STORE|MSG_DONT_WRAP, |
| 245 | MA_CHANNEL"." + lower_case(channel), 0, sender); |
| 246 | } |
| 247 | return 0; |
| 248 | } |
| 249 | |
Zesstra | 60df911 | 2020-08-18 00:01:58 +0200 | [diff] [blame] | 250 | // Defines fuer den Zugriff auf die Channeldaten in der vom CHANNELD |
| 251 | // erhaltenen Kanalliste. |
| 252 | #define I_MEMBER 0 |
| 253 | #define I_ACCESS 1 |
| 254 | #define I_INFO 2 |
| 255 | #define I_SUPERVISOR 3 |
| 256 | #define I_NAME 4 |
MG Mud User | 88f1247 | 2016-06-24 23:31:02 +0200 | [diff] [blame] | 257 | |
Arathorn | 78c0837 | 2019-12-11 20:14:23 +0100 | [diff] [blame] | 258 | private void createList(mapping ch_list, string* p_channels, |
| 259 | int show_only_subscribed) { |
| 260 | // Kopfzeile der Tabelle erstellen. |
| 261 | string listhead = |
| 262 | sprintf("%-12.12' 's [A] %|12' 's (%-3' 's) %-42.42s\n", |
| 263 | "Name", "Eigner", "Sp", "Beschreibung"); |
| 264 | // Linie drunter. |
| 265 | listhead += ("-"*78 + "\n"); |
| 266 | |
| 267 | // Rest der Daten erstmal in einem Array zusammenstellen, um es |
| 268 | // anschliessend sortieren zu koennen. |
| 269 | string* entries = ({}); |
| 270 | |
| 271 | object* ch_members; |
| 272 | string|object ch_master; |
| 273 | string ch_real_name, ch_description; |
| 274 | closure|string ch_access; |
| 275 | closure|string ch_info; |
| 276 | string sh; |
| 277 | |
| 278 | foreach(string chname, <object*|closure|string|object>* chdata : ch_list) |
| 279 | { |
| 280 | // Wenn nur abonnierte Ebenen aufgelistet werden sollen, dann alle |
| 281 | // ueberspringen, die nicht in P_CHANNELS stehen. |
| 282 | int is_subscribed = (member(p_channels, chname) > -1); |
| 283 | if (show_only_subscribed && !is_subscribed) |
| 284 | continue; |
| 285 | |
| 286 | ch_members = chdata[I_MEMBER]; |
Zesstra | 60df911 | 2020-08-18 00:01:58 +0200 | [diff] [blame] | 287 | ch_master = chdata[I_SUPERVISOR]; |
Arathorn | 78c0837 | 2019-12-11 20:14:23 +0100 | [diff] [blame] | 288 | ch_access = chdata[I_ACCESS]; |
| 289 | ch_real_name = chdata[I_NAME]; |
| 290 | ch_info = chdata[I_INFO]; |
| 291 | sh = ""; |
| 292 | |
| 293 | // Ist eine Closure als I_INFO eingetragen, zu der es auch ein Objekt |
| 294 | // gibt, tragen wir deren Rueckgabewert als Beschreibung ein. |
| 295 | if (closurep(ch_info) && objectp(query_closure_object(ch_info))) { |
| 296 | ch_description = funcall(ch_info); |
| 297 | } |
| 298 | // Ist es ein String, wird er unveraendert uebernommen. |
| 299 | else if (stringp(ch_info)) { |
| 300 | ch_description = ch_info; |
| 301 | } |
| 302 | // Sollte nirgends etwas eingetragen sein, oder die Closure 0 zurueck- |
| 303 | // gegeben haben, gibt es eine Defaultbeschreibung. Man haette die |
| 304 | // Variable auch schon mit dem Default initialisieren koennen, der kann |
| 305 | // aber bei Rueckgabe von 0 aus der Closure wieder ueberschrieben werden. |
| 306 | // Daher passiert das erst hier. |
| 307 | ch_description ||= "- Keine Beschreibung -"; |
| 308 | |
| 309 | // Wir brauchen noch das vom Spieler festgelegte Kuerzel fuer die aktuell |
| 310 | // bearbeitete Ebene, falls vorhanden, um es in die Liste eintragen |
| 311 | // zu koennen. |
| 312 | foreach(string _sh_cut, string _chan_name : shortcut) { |
| 313 | if ( lower_case(_chan_name) == chname ) { |
| 314 | sh = _sh_cut; |
| 315 | break; |
| 316 | } |
| 317 | } |
| 318 | |
| 319 | // Jetzt haben wir endlich alle Infos beisammen und koennen die |
| 320 | // Eintraege zusammenbauen. |
| 321 | entries += ({ |
| 322 | sprintf("%-12.12'.'s %c[%-1.1s] %|12.12' 's (%-|3' 'd) %-42.42s\n", |
| 323 | ch_real_name, |
| 324 | is_subscribed ? '*' : ' ', |
| 325 | sh, |
| 326 | ch_master ? getName(ch_master) : getName(ch_access), |
Zesstra | e40de3a | 2020-09-24 00:12:12 +0200 | [diff] [blame] | 327 | sizeof(ch_members), |
Arathorn | 78c0837 | 2019-12-11 20:14:23 +0100 | [diff] [blame] | 328 | ch_description |
| 329 | ) }); |
| 330 | } |
| 331 | |
| 332 | // alphabetisch sortieren |
| 333 | entries = sort_array(entries, #'>); |
| 334 | |
| 335 | More( listhead + // Listenkopf |
| 336 | implode(entries, "") + // Eintraege |
| 337 | "-"*78+"\n" ); // Linie drunter |
| 338 | } |
| 339 | |
| 340 | private string|string* getChannel(string ch) |
MG Mud User | 88f1247 | 2016-06-24 23:31:02 +0200 | [diff] [blame] | 341 | { |
Arathorn | 85de760 | 2019-11-28 23:04:03 +0100 | [diff] [blame] | 342 | if (!sizeof(ch)) |
Arathorn | 0076469 | 2019-11-27 22:09:31 +0100 | [diff] [blame] | 343 | ch = QueryProp(P_STD_CHANNEL); |
Arathorn | 85de760 | 2019-11-28 23:04:03 +0100 | [diff] [blame] | 344 | if (shortcut && shortcut[ch]) |
Arathorn | 0076469 | 2019-11-27 22:09:31 +0100 | [diff] [blame] | 345 | ch = shortcut[ch]; |
Arathorn | 78c0837 | 2019-12-11 20:14:23 +0100 | [diff] [blame] | 346 | return CHMASTER->find(ch, ME); |
MG Mud User | 88f1247 | 2016-06-24 23:31:02 +0200 | [diff] [blame] | 347 | } |
| 348 | |
MG Mud User | 88f1247 | 2016-06-24 23:31:02 +0200 | [diff] [blame] | 349 | int ChannelParser(string args) |
| 350 | { |
Arathorn | 78c0837 | 2019-12-11 20:14:23 +0100 | [diff] [blame] | 351 | string|string* ch; |
MG Mud User | 88f1247 | 2016-06-24 23:31:02 +0200 | [diff] [blame] | 352 | int pos, type, err; |
Arathorn | 78c0837 | 2019-12-11 20:14:23 +0100 | [diff] [blame] | 353 | string tmp; |
MG Mud User | 88f1247 | 2016-06-24 23:31:02 +0200 | [diff] [blame] | 354 | notify_fail("Benutzung: -<Ebene>[ ]['|:|;]<Text>\n" |
| 355 | " -<Ebene>[+|-|?|!|*]\n" |
| 356 | " -?\n"); |
Arathorn | 78c0837 | 2019-12-11 20:14:23 +0100 | [diff] [blame] | 357 | |
Arathorn | b794a19 | 2020-08-06 21:51:28 +0200 | [diff] [blame] | 358 | args = _unparsed_args(); |
Arathorn | 78c0837 | 2019-12-11 20:14:23 +0100 | [diff] [blame] | 359 | string|string* cmd = query_verb(); |
Arathorn | 85de760 | 2019-11-28 23:04:03 +0100 | [diff] [blame] | 360 | if (!cmd && !args) |
| 361 | return 0; |
| 362 | |
| 363 | if (!args) |
| 364 | args = ""; |
| 365 | |
MG Mud User | 88f1247 | 2016-06-24 23:31:02 +0200 | [diff] [blame] | 366 | cmd = cmd[1..]; |
Arathorn | 78c0837 | 2019-12-11 20:14:23 +0100 | [diff] [blame] | 367 | cmd = regexplode(cmd, "^" CHANNELCMDS "*" "([+-]|\\!|\\?|\\*)*"); |
Arathorn | 85de760 | 2019-11-28 23:04:03 +0100 | [diff] [blame] | 368 | if (sizeof(cmd) > 1) |
MG Mud User | 88f1247 | 2016-06-24 23:31:02 +0200 | [diff] [blame] | 369 | { |
| 370 | //z.B. cmd= ({"","allgemein",":testet"}) |
Arathorn | 85de760 | 2019-11-28 23:04:03 +0100 | [diff] [blame] | 371 | if (sizeof(cmd[1]) > 1 && strstr("+-?!*", cmd[1][<1..<1]) > -1) |
MG Mud User | 88f1247 | 2016-06-24 23:31:02 +0200 | [diff] [blame] | 372 | tmp = cmd[1][0..<2]; |
| 373 | else |
| 374 | tmp = cmd[1]; |
Arathorn | 85de760 | 2019-11-28 23:04:03 +0100 | [diff] [blame] | 375 | |
| 376 | if (cmd[1] != "?" && cmd[1] != "!") |
Zesstra | 57a693e | 2019-01-06 22:08:24 +0100 | [diff] [blame] | 377 | { |
| 378 | ch = getChannel(tmp); |
Arathorn | 85de760 | 2019-11-28 23:04:03 +0100 | [diff] [blame] | 379 | if (pointerp(ch)) |
MG Mud User | 88f1247 | 2016-06-24 23:31:02 +0200 | [diff] [blame] | 380 | { |
| 381 | notify_fail("Diese Angabe war nicht eindeutig! " |
Arathorn | 78c0837 | 2019-12-11 20:14:23 +0100 | [diff] [blame] | 382 | "Folgende Ebenen passen:\n"+ |
| 383 | implode(ch, ", ")+"\n"); |
MG Mud User | 88f1247 | 2016-06-24 23:31:02 +0200 | [diff] [blame] | 384 | return 0; |
| 385 | } |
Arathorn | 85de760 | 2019-11-28 23:04:03 +0100 | [diff] [blame] | 386 | else if (!ch) |
| 387 | { |
| 388 | notify_fail("Die Ebene '"+tmp+ "' gibt es nicht!\n"); |
| 389 | return 0; |
| 390 | } |
Zesstra | 57a693e | 2019-01-06 22:08:24 +0100 | [diff] [blame] | 391 | } |
Arathorn | 85de760 | 2019-11-28 23:04:03 +0100 | [diff] [blame] | 392 | |
MG Mud User | 88f1247 | 2016-06-24 23:31:02 +0200 | [diff] [blame] | 393 | if (sizeof(cmd[1])) { |
Arathorn | 85de760 | 2019-11-28 23:04:03 +0100 | [diff] [blame] | 394 | switch (cmd[1][<1]) { |
| 395 | case '+': |
Arathorn | 78c0837 | 2019-12-11 20:14:23 +0100 | [diff] [blame] | 396 | switch (CHMASTER->join(ch, ME)) |
Arathorn | 85de760 | 2019-11-28 23:04:03 +0100 | [diff] [blame] | 397 | { |
| 398 | case E_ACCESS_DENIED: |
| 399 | notify_fail("Du darfst an die Ebene '"+ch+"' nicht heran.\n"); |
| 400 | return 0; |
| 401 | case E_ALREADY_JOINED: |
| 402 | notify_fail("Du hast diese Ebene schon betreten!\n"); |
| 403 | return 0; |
| 404 | default: |
| 405 | break; |
| 406 | } |
Arathorn | 78c0837 | 2019-12-11 20:14:23 +0100 | [diff] [blame] | 407 | tell_object(ME,"Du betrittst die Ebene '"+ch+"'.\n"); |
Arathorn | 85de760 | 2019-11-28 23:04:03 +0100 | [diff] [blame] | 408 | if (member(QueryProp(P_CHANNELS), ch = lower_case(ch)) == -1) |
| 409 | SetProp(P_CHANNELS, QueryProp(P_CHANNELS) + ({ ch })); |
| 410 | return 1; |
| 411 | |
| 412 | case '-': |
Arathorn | 78c0837 | 2019-12-11 20:14:23 +0100 | [diff] [blame] | 413 | switch (CHMASTER->leave(ch, ME)) |
Arathorn | 85de760 | 2019-11-28 23:04:03 +0100 | [diff] [blame] | 414 | { |
| 415 | case E_ACCESS_DENIED: |
Arathorn | 78c0837 | 2019-12-11 20:14:23 +0100 | [diff] [blame] | 416 | tell_object(ME,"Du kannst die Ebene '"+ch+"' nicht " |
| 417 | "verlassen.\n"); |
Arathorn | 85de760 | 2019-11-28 23:04:03 +0100 | [diff] [blame] | 418 | break; |
| 419 | case E_NOT_MEMBER: |
Arathorn | 78c0837 | 2019-12-11 20:14:23 +0100 | [diff] [blame] | 420 | tell_object(ME,"Wie willst Du eine Ebene verlassen, welche Du " |
| 421 | "nicht betreten hast?\n"); |
Arathorn | 85de760 | 2019-11-28 23:04:03 +0100 | [diff] [blame] | 422 | break; |
| 423 | default: |
Arathorn | 78c0837 | 2019-12-11 20:14:23 +0100 | [diff] [blame] | 424 | tell_object(ME,"Du verlaesst die Ebene '"+ch+"'.\n"); |
Arathorn | 85de760 | 2019-11-28 23:04:03 +0100 | [diff] [blame] | 425 | SetProp(P_CHANNELS, |
| 426 | QueryProp(P_CHANNELS) - ({ lower_case(ch), ch })); |
| 427 | break; |
| 428 | } |
| 429 | return 1; |
| 430 | |
| 431 | case '!': |
| 432 | case '?': |
Arathorn | 78c0837 | 2019-12-11 20:14:23 +0100 | [diff] [blame] | 433 | mapping l = CHMASTER->list(ME); |
| 434 | if (mappingp(l)) |
Arathorn | 85de760 | 2019-11-28 23:04:03 +0100 | [diff] [blame] | 435 | { |
Arathorn | 78c0837 | 2019-12-11 20:14:23 +0100 | [diff] [blame] | 436 | // Es wurde ein Channel angegeben, dessen Infos gefragt sind. |
Arathorn | 85de760 | 2019-11-28 23:04:03 +0100 | [diff] [blame] | 437 | if (stringp(ch) && sizeof(ch) && pointerp(l[ch = lower_case(ch)])) |
| 438 | { |
Arathorn | 78c0837 | 2019-12-11 20:14:23 +0100 | [diff] [blame] | 439 | <object*|closure|string|object>* chdata = l[ch]; |
| 440 | string* m = |
Zesstra | e40de3a | 2020-09-24 00:12:12 +0200 | [diff] [blame] | 441 | sort_array(map(chdata[I_MEMBER], #'getName, WER), #'>); |
Arathorn | 78c0837 | 2019-12-11 20:14:23 +0100 | [diff] [blame] | 442 | |
| 443 | string wen; |
| 444 | switch(sizeof(m)) { |
| 445 | case 1: wen = "ein Gesicht"; break; |
| 446 | case 0: wen = "niemanden"; break; |
| 447 | // TODO: mittels Zahlwoerter-Objekt die Zahl als Text |
| 448 | // ausgeben? |
| 449 | default: wen = sprintf("%d Gesichter", sizeof(m)); break; |
| 450 | } |
| 451 | |
| 452 | tell_object(ME, |
| 453 | chdata[I_NAME]+", "+funcall(chdata[I_INFO])+".\n" + |
| 454 | "Du siehst "+wen+" auf der Ebene '"+chdata[I_NAME]+"':\n"+ |
Zesstra | 60df911 | 2020-08-18 00:01:58 +0200 | [diff] [blame] | 455 | break_string(CountUp(m), 78) + getName(chdata[I_SUPERVISOR]) |
| 456 | + " hat das Sagen auf dieser Ebene.\n"); |
Arathorn | 85de760 | 2019-11-28 23:04:03 +0100 | [diff] [blame] | 457 | } |
Arathorn | 78c0837 | 2019-12-11 20:14:23 +0100 | [diff] [blame] | 458 | // kein Channel angegeben, dann Gesamtliste erzeugen |
Arathorn | 85de760 | 2019-11-28 23:04:03 +0100 | [diff] [blame] | 459 | else |
| 460 | { |
Arathorn | 78c0837 | 2019-12-11 20:14:23 +0100 | [diff] [blame] | 461 | // Wenn nur die abonnierten angezeigt werden sollen |
| 462 | // (Kommando -!), wird die Bedingung im 3. Argument == 1, so |
| 463 | // dass createList() die reduzierte Tabelle erzeugt. |
| 464 | createList(l, QueryProp(P_CHANNELS), (cmd[1][<1] == '!')); |
Arathorn | 85de760 | 2019-11-28 23:04:03 +0100 | [diff] [blame] | 465 | } |
| 466 | } |
| 467 | return 1; |
| 468 | |
| 469 | case '*': |
Arathorn | 78c0837 | 2019-12-11 20:14:23 +0100 | [diff] [blame] | 470 | int|<int|string>** hist = CHMASTER->history(ch, ME); |
Arathorn | 85de760 | 2019-11-28 23:04:03 +0100 | [diff] [blame] | 471 | if (!pointerp(hist) || !sizeof(hist)) |
| 472 | { |
Arathorn | 78c0837 | 2019-12-11 20:14:23 +0100 | [diff] [blame] | 473 | tell_object(ME,"Es ist keine Geschichte fuer '"+ch+ |
| 474 | "' verfuegbar.\n"); |
Arathorn | 85de760 | 2019-11-28 23:04:03 +0100 | [diff] [blame] | 475 | return 1; |
| 476 | } |
| 477 | |
Arathorn | 85de760 | 2019-11-28 23:04:03 +0100 | [diff] [blame] | 478 | int amount = to_int(cmd[2]); |
| 479 | if (amount <= 0 || amount >= sizeof(hist)) |
| 480 | amount = sizeof(hist); |
| 481 | |
Arathorn | 78c0837 | 2019-12-11 20:14:23 +0100 | [diff] [blame] | 482 | string txt = "Folgendes ist auf '"+ch+"' passiert:\n" + |
| 483 | implode(map(hist[<amount..], #'ChannelMessage, 1), ""); |
MG Mud User | 88f1247 | 2016-06-24 23:31:02 +0200 | [diff] [blame] | 484 | More(txt); |
Arathorn | 85de760 | 2019-11-28 23:04:03 +0100 | [diff] [blame] | 485 | return 1; |
| 486 | |
| 487 | default: |
| 488 | break; |
Zesstra | 57a693e | 2019-01-06 22:08:24 +0100 | [diff] [blame] | 489 | } |
MG Mud User | 88f1247 | 2016-06-24 23:31:02 +0200 | [diff] [blame] | 490 | } |
| 491 | } |
Arathorn | 85de760 | 2019-11-28 23:04:03 +0100 | [diff] [blame] | 492 | |
Arathorn | 78c0837 | 2019-12-11 20:14:23 +0100 | [diff] [blame] | 493 | cmd = implode(cmd[2..], ""); |
| 494 | if (sizeof(cmd)) |
Arathorn | 85de760 | 2019-11-28 23:04:03 +0100 | [diff] [blame] | 495 | args = cmd + (sizeof(args) ? " " : "") + args; |
MG Mud User | 88f1247 | 2016-06-24 23:31:02 +0200 | [diff] [blame] | 496 | |
| 497 | // KOntrollchars ausfiltern. |
Arathorn | 78c0837 | 2019-12-11 20:14:23 +0100 | [diff] [blame] | 498 | args = regreplace(args, "[[:cntrl:]]", "", RE_PCRE|RE_GLOBAL); |
Arathorn | 85de760 | 2019-11-28 23:04:03 +0100 | [diff] [blame] | 499 | if (!sizeof(args)) |
| 500 | return 0; |
MG Mud User | 88f1247 | 2016-06-24 23:31:02 +0200 | [diff] [blame] | 501 | |
| 502 | //Wenn cmd leer ist: MSG_SAY |
Arathorn | 85de760 | 2019-11-28 23:04:03 +0100 | [diff] [blame] | 503 | if (!sizeof(cmd)) |
Arathorn | 78c0837 | 2019-12-11 20:14:23 +0100 | [diff] [blame] | 504 | { |
Arathorn | 85de760 | 2019-11-28 23:04:03 +0100 | [diff] [blame] | 505 | type = MSG_SAY; |
Arathorn | 78c0837 | 2019-12-11 20:14:23 +0100 | [diff] [blame] | 506 | } |
Arathorn | 85de760 | 2019-11-28 23:04:03 +0100 | [diff] [blame] | 507 | else |
| 508 | { |
| 509 | switch (cmd[0]) |
MG Mud User | 88f1247 | 2016-06-24 23:31:02 +0200 | [diff] [blame] | 510 | { |
Arathorn | 85de760 | 2019-11-28 23:04:03 +0100 | [diff] [blame] | 511 | case ':' : |
| 512 | type = MSG_EMOTE; |
| 513 | args = args[1..]; |
| 514 | break; |
| 515 | case ';' : |
| 516 | type = MSG_GEMOTE; |
| 517 | args = args[1..]; |
| 518 | break; |
| 519 | case '\'': |
| 520 | args = args[1..]; |
| 521 | // Der Fallthrough in default ist hier Absicht. |
| 522 | default : |
| 523 | type = MSG_SAY; |
| 524 | break; |
MG Mud User | 88f1247 | 2016-06-24 23:31:02 +0200 | [diff] [blame] | 525 | } |
| 526 | } |
Arathorn | 85de760 | 2019-11-28 23:04:03 +0100 | [diff] [blame] | 527 | |
| 528 | if (!ch || !sizeof(ch)) |
| 529 | ch = QueryProp(P_STD_CHANNEL); |
| 530 | |
Arathorn | 78c0837 | 2019-12-11 20:14:23 +0100 | [diff] [blame] | 531 | err = CHMASTER->send(ch, ME, args, type); |
Arathorn | 85de760 | 2019-11-28 23:04:03 +0100 | [diff] [blame] | 532 | if (err < 0) |
| 533 | { |
Arathorn | 78c0837 | 2019-12-11 20:14:23 +0100 | [diff] [blame] | 534 | err = CHMASTER->join(ch, ME); |
Arathorn | 85de760 | 2019-11-28 23:04:03 +0100 | [diff] [blame] | 535 | if (!err) |
MG Mud User | 88f1247 | 2016-06-24 23:31:02 +0200 | [diff] [blame] | 536 | { |
Arathorn | 78c0837 | 2019-12-11 20:14:23 +0100 | [diff] [blame] | 537 | ch = lower_case(ch); |
| 538 | if (member(QueryProp(P_CHANNELS), ch) == -1) |
MG Mud User | 88f1247 | 2016-06-24 23:31:02 +0200 | [diff] [blame] | 539 | SetProp(P_CHANNELS, QueryProp(P_CHANNELS) + ({ ch })); |
Arathorn | 78c0837 | 2019-12-11 20:14:23 +0100 | [diff] [blame] | 540 | err = CHMASTER->send(ch, ME, args, type); |
MG Mud User | 88f1247 | 2016-06-24 23:31:02 +0200 | [diff] [blame] | 541 | } |
Arathorn | 85de760 | 2019-11-28 23:04:03 +0100 | [diff] [blame] | 542 | } |
MG Mud User | 88f1247 | 2016-06-24 23:31:02 +0200 | [diff] [blame] | 543 | |
Arathorn | 85de760 | 2019-11-28 23:04:03 +0100 | [diff] [blame] | 544 | switch (err) |
MG Mud User | 88f1247 | 2016-06-24 23:31:02 +0200 | [diff] [blame] | 545 | { |
Arathorn | 85de760 | 2019-11-28 23:04:03 +0100 | [diff] [blame] | 546 | case E_ACCESS_DENIED: |
| 547 | notify_fail("Auf der Ebene '"+ch+"' darfst Du nichts sagen.\n"); |
| 548 | return 0; |
| 549 | case E_NOT_MEMBER: |
| 550 | notify_fail("Du hast die Ebene '"+ch+"' nicht betreten!\n"); |
| 551 | return 0; |
MG Mud User | 88f1247 | 2016-06-24 23:31:02 +0200 | [diff] [blame] | 552 | } |
| 553 | return 1; |
| 554 | } |
| 555 | |
| 556 | int ChannelAdmin(string args) |
| 557 | { |
Arathorn | 85de760 | 2019-11-28 23:04:03 +0100 | [diff] [blame] | 558 | args = _unparsed_args(); |
| 559 | |
Arathorn | 78c0837 | 2019-12-11 20:14:23 +0100 | [diff] [blame] | 560 | string target_channel, descr, _sh_cut; |
| 561 | string|string* chans; |
MG Mud User | 88f1247 | 2016-06-24 23:31:02 +0200 | [diff] [blame] | 562 | notify_fail("Benutzung: ebene <Abkuerzung>=<Ebene>\n" |
| 563 | " ebene <Abkuerzung>=\n" |
| 564 | " ebene abkuerzungen [standard]\n" |
| 565 | " ebene standard <Ebene>\n" |
| 566 | " ebene an|ein|aus\n" |
| 567 | +(QueryProp(P_LEVEL) >= 5 ? |
| 568 | " ebene neu <Name> <Bezeichnung>\n" |
Arathorn | 85de760 | 2019-11-28 23:04:03 +0100 | [diff] [blame] | 569 | " ebene beschreibung <Name> <Beschreibung>\n" : "") |
Arathorn | 78c0837 | 2019-12-11 20:14:23 +0100 | [diff] [blame] | 570 | +(IS_ARCH(ME) ? |
Arathorn | 85de760 | 2019-11-28 23:04:03 +0100 | [diff] [blame] | 571 | " ebene kill <Name>\n" |
| 572 | " ebene clear <Name>\n": "")); |
| 573 | |
| 574 | if (!args || !sizeof(args)) |
| 575 | return 0; |
| 576 | |
Arathorn | 78c0837 | 2019-12-11 20:14:23 +0100 | [diff] [blame] | 577 | if (sscanf(args, "kill %s", target_channel) && IS_ARCH(ME)) |
MG Mud User | 88f1247 | 2016-06-24 23:31:02 +0200 | [diff] [blame] | 578 | { |
Arathorn | 78c0837 | 2019-12-11 20:14:23 +0100 | [diff] [blame] | 579 | chans = CHMASTER->find(target_channel, ME); |
Arathorn | 85de760 | 2019-11-28 23:04:03 +0100 | [diff] [blame] | 580 | |
Arathorn | 78c0837 | 2019-12-11 20:14:23 +0100 | [diff] [blame] | 581 | if (!chans) |
| 582 | { |
| 583 | notify_fail("Ebene '"+target_channel+"' nicht gefunden!\n"); |
Arathorn | 85de760 | 2019-11-28 23:04:03 +0100 | [diff] [blame] | 584 | return 0; |
MG Mud User | 88f1247 | 2016-06-24 23:31:02 +0200 | [diff] [blame] | 585 | } |
Arathorn | 78c0837 | 2019-12-11 20:14:23 +0100 | [diff] [blame] | 586 | else if (pointerp(chans)) |
| 587 | { |
| 588 | notify_fail( |
| 589 | "Das war keine eindeutige Angabe! Folgende Ebenen passen:\n"+ |
| 590 | break_string(CountUp(chans), 78)); |
| 591 | return 0; |
| 592 | } |
| 593 | else if (CHMASTER->remove_channel(target_channel, ME)) |
| 594 | { |
| 595 | notify_fail("Die Ebene '"+target_channel+"' lies sich nicht " |
Arathorn | 85de760 | 2019-11-28 23:04:03 +0100 | [diff] [blame] | 596 | "entfernen!\n"); |
| 597 | return 0; |
MG Mud User | 88f1247 | 2016-06-24 23:31:02 +0200 | [diff] [blame] | 598 | } |
Arathorn | 85de760 | 2019-11-28 23:04:03 +0100 | [diff] [blame] | 599 | |
Arathorn | 78c0837 | 2019-12-11 20:14:23 +0100 | [diff] [blame] | 600 | tell_object(ME,"Du entfernst die Ebene '"+target_channel+"'.\n"); |
MG Mud User | 88f1247 | 2016-06-24 23:31:02 +0200 | [diff] [blame] | 601 | return 1; |
| 602 | } |
Arathorn | 85de760 | 2019-11-28 23:04:03 +0100 | [diff] [blame] | 603 | |
Arathorn | 78c0837 | 2019-12-11 20:14:23 +0100 | [diff] [blame] | 604 | if (sscanf(args, "clear %s", target_channel) && IS_ARCH(ME)) |
MG Mud User | 88f1247 | 2016-06-24 23:31:02 +0200 | [diff] [blame] | 605 | { |
Arathorn | 78c0837 | 2019-12-11 20:14:23 +0100 | [diff] [blame] | 606 | chans = CHMASTER->find(target_channel, ME); |
| 607 | |
| 608 | if (!chans) |
| 609 | { |
| 610 | notify_fail("Ebene '"+target_channel+"' nicht gefunden!\n"); |
| 611 | return 0; |
| 612 | } |
| 613 | else if (pointerp(chans)) |
| 614 | { |
| 615 | notify_fail( |
| 616 | "Das war keine eindeutige Angabe! Folgende Ebenen passen:\n"+ |
| 617 | break_string(CountUp(chans), 78)); |
| 618 | return 0; |
| 619 | } |
| 620 | else if (CHMASTER->clear_history(target_channel, ME) == E_ACCESS_DENIED) |
| 621 | { |
| 622 | notify_fail("Der Verlauf zur Ebene '"+target_channel+"' liess sich " |
| 623 | "nicht entfernen!\n"); |
| 624 | return 0; |
| 625 | } |
| 626 | |
| 627 | tell_object(ME,"Du entfernst den Verlauf zur Ebene '"+target_channel+ |
| 628 | "'.\n"); |
| 629 | return 1; |
| 630 | } |
| 631 | |
| 632 | if (sscanf(args, "neu %s %s", target_channel, descr) == 2) |
| 633 | { |
| 634 | notify_fail(break_string("Neue Ebenen kannst Du erst erstellen, wenn " |
| 635 | "Du Spielerstufe 5 erreicht hast.", 78)); |
Arathorn | 85de760 | 2019-11-28 23:04:03 +0100 | [diff] [blame] | 636 | if (QueryProp(P_LEVEL) < 5) |
Arathorn | 85de760 | 2019-11-28 23:04:03 +0100 | [diff] [blame] | 637 | return 0; |
Arathorn | 85de760 | 2019-11-28 23:04:03 +0100 | [diff] [blame] | 638 | |
Arathorn | 78c0837 | 2019-12-11 20:14:23 +0100 | [diff] [blame] | 639 | notify_fail("Der Name '"+target_channel+"' ist nicht konform!\n"); |
| 640 | if (!sizeof(regexp(({target_channel}), "^" CHANNELCMDS CHANNELCMDS "*"))) |
Arathorn | 85de760 | 2019-11-28 23:04:03 +0100 | [diff] [blame] | 641 | return 0; |
Arathorn | 85de760 | 2019-11-28 23:04:03 +0100 | [diff] [blame] | 642 | |
Arathorn | 78c0837 | 2019-12-11 20:14:23 +0100 | [diff] [blame] | 643 | notify_fail("Der Name '"+target_channel+"' ist zu lang.\n"); |
| 644 | if (sizeof(target_channel) > 20) |
Arathorn | 85de760 | 2019-11-28 23:04:03 +0100 | [diff] [blame] | 645 | return 0; |
Arathorn | 85de760 | 2019-11-28 23:04:03 +0100 | [diff] [blame] | 646 | |
Arathorn | 78c0837 | 2019-12-11 20:14:23 +0100 | [diff] [blame] | 647 | notify_fail("Diese Ebene darfst du nicht erschaffen!\n"); |
| 648 | if (CHMASTER->new(target_channel, ME, descr) == E_ACCESS_DENIED) |
Arathorn | 85de760 | 2019-11-28 23:04:03 +0100 | [diff] [blame] | 649 | return 0; |
Arathorn | 78c0837 | 2019-12-11 20:14:23 +0100 | [diff] [blame] | 650 | |
| 651 | tell_object(ME,"Du erschaffst die Ebene '"+target_channel+"'.\n"); |
| 652 | SetProp(P_CHANNELS, QueryProp(P_CHANNELS) + |
| 653 | ({lower_case(target_channel)})); |
Arathorn | 85de760 | 2019-11-28 23:04:03 +0100 | [diff] [blame] | 654 | return 1; |
MG Mud User | 88f1247 | 2016-06-24 23:31:02 +0200 | [diff] [blame] | 655 | } |
Arathorn | 85de760 | 2019-11-28 23:04:03 +0100 | [diff] [blame] | 656 | |
Arathorn | 78c0837 | 2019-12-11 20:14:23 +0100 | [diff] [blame] | 657 | if (sscanf(args, "beschreibung %s %s", target_channel, descr) == 2) |
MG Mud User | 88f1247 | 2016-06-24 23:31:02 +0200 | [diff] [blame] | 658 | { |
Arathorn | 78c0837 | 2019-12-11 20:14:23 +0100 | [diff] [blame] | 659 | chans = CHMASTER->find(target_channel, ME); |
| 660 | |
| 661 | if (!chans) |
Arathorn | 85de760 | 2019-11-28 23:04:03 +0100 | [diff] [blame] | 662 | { |
Arathorn | 78c0837 | 2019-12-11 20:14:23 +0100 | [diff] [blame] | 663 | notify_fail("Ebene '"+target_channel+"' nicht gefunden!\n"); |
| 664 | return 0; |
| 665 | } |
| 666 | else if (pointerp(chans)) |
| 667 | { |
| 668 | notify_fail( |
| 669 | "Das war keine eindeutige Angabe! Folgende Ebenen passen:\n"+ |
| 670 | break_string(CountUp(chans), 78)); |
Arathorn | 85de760 | 2019-11-28 23:04:03 +0100 | [diff] [blame] | 671 | return 0; |
| 672 | } |
| 673 | |
Arathorn | 78c0837 | 2019-12-11 20:14:23 +0100 | [diff] [blame] | 674 | mapping ch = CHMASTER->list(ME); |
| 675 | notify_fail("Du bist nicht berechtigt, die Beschreibung der Ebene" |
| 676 | " '"+target_channel+"' zu aendern.\n"); |
Zesstra | 60df911 | 2020-08-18 00:01:58 +0200 | [diff] [blame] | 677 | if (ch[lower_case(chans)][I_SUPERVISOR] != ME) |
Arathorn | 85de760 | 2019-11-28 23:04:03 +0100 | [diff] [blame] | 678 | return 0; |
Arathorn | 78c0837 | 2019-12-11 20:14:23 +0100 | [diff] [blame] | 679 | |
| 680 | ch[lower_case(target_channel)][I_INFO] = descr; |
| 681 | tell_object(ME,"Die Ebene '"+target_channel+"' hat ab sofort die " |
| 682 | "Beschreibung:\n"+descr+"\n"); |
MG Mud User | 88f1247 | 2016-06-24 23:31:02 +0200 | [diff] [blame] | 683 | return 1; |
| 684 | } |
Arathorn | 85de760 | 2019-11-28 23:04:03 +0100 | [diff] [blame] | 685 | |
Arathorn | 78c0837 | 2019-12-11 20:14:23 +0100 | [diff] [blame] | 686 | if (sscanf(args, "%s=%s", _sh_cut, target_channel) == 2 && |
| 687 | sizeof(target_channel)) |
MG Mud User | 88f1247 | 2016-06-24 23:31:02 +0200 | [diff] [blame] | 688 | { |
Arathorn | 78c0837 | 2019-12-11 20:14:23 +0100 | [diff] [blame] | 689 | chans = CHMASTER->find(target_channel, ME); |
| 690 | |
| 691 | if (!chans) |
Arathorn | 85de760 | 2019-11-28 23:04:03 +0100 | [diff] [blame] | 692 | { |
Arathorn | 78c0837 | 2019-12-11 20:14:23 +0100 | [diff] [blame] | 693 | notify_fail("Ebene '"+target_channel+"' nicht gefunden!\n"); |
| 694 | return 0; |
| 695 | } |
| 696 | else if (pointerp(chans)) |
| 697 | { |
| 698 | notify_fail( |
| 699 | "Das war keine eindeutige Angabe! Folgende Ebenen passen:\n"+ |
| 700 | break_string(CountUp(chans), 78)); |
Arathorn | 85de760 | 2019-11-28 23:04:03 +0100 | [diff] [blame] | 701 | return 0; |
| 702 | } |
| 703 | |
Arathorn | 78c0837 | 2019-12-11 20:14:23 +0100 | [diff] [blame] | 704 | mapping shortcut_list = QueryProp(P_CHANNEL_SHORT) || ([]); |
| 705 | m_add(shortcut_list, _sh_cut, chans); |
| 706 | SetProp(P_CHANNEL_SHORT, shortcut_list); |
Arathorn | 85de760 | 2019-11-28 23:04:03 +0100 | [diff] [blame] | 707 | |
MG Mud User | 88f1247 | 2016-06-24 23:31:02 +0200 | [diff] [blame] | 708 | shortcut = QueryProp(P_CHANNEL_SHORT); |
Arathorn | 85de760 | 2019-11-28 23:04:03 +0100 | [diff] [blame] | 709 | |
Arathorn | 78c0837 | 2019-12-11 20:14:23 +0100 | [diff] [blame] | 710 | tell_object(ME,"'"+_sh_cut+"' wird jetzt als Abkuerzung fuer '"+chans+ |
| 711 | "' anerkannt.\n"); |
MG Mud User | 88f1247 | 2016-06-24 23:31:02 +0200 | [diff] [blame] | 712 | return 1; |
| 713 | } |
Arathorn | 85de760 | 2019-11-28 23:04:03 +0100 | [diff] [blame] | 714 | |
Arathorn | 78c0837 | 2019-12-11 20:14:23 +0100 | [diff] [blame] | 715 | if (sscanf(args, "%s=", _sh_cut)) |
MG Mud User | 88f1247 | 2016-06-24 23:31:02 +0200 | [diff] [blame] | 716 | { |
Arathorn | 85de760 | 2019-11-28 23:04:03 +0100 | [diff] [blame] | 717 | SetProp(P_CHANNEL_SHORT, |
Arathorn | 78c0837 | 2019-12-11 20:14:23 +0100 | [diff] [blame] | 718 | m_delete(QueryProp(P_CHANNEL_SHORT) || ([]), _sh_cut)); |
MG Mud User | 88f1247 | 2016-06-24 23:31:02 +0200 | [diff] [blame] | 719 | shortcut = QueryProp(P_CHANNEL_SHORT); |
Arathorn | 78c0837 | 2019-12-11 20:14:23 +0100 | [diff] [blame] | 720 | tell_object(ME,"Du loeschst die Abkuerzung '"+_sh_cut+"'.\n"); |
MG Mud User | 88f1247 | 2016-06-24 23:31:02 +0200 | [diff] [blame] | 721 | return 1; |
| 722 | } |
Arathorn | 85de760 | 2019-11-28 23:04:03 +0100 | [diff] [blame] | 723 | |
| 724 | if (args == "an" || args == "ein") |
MG Mud User | 88f1247 | 2016-06-24 23:31:02 +0200 | [diff] [blame] | 725 | { |
Arathorn | 85de760 | 2019-11-28 23:04:03 +0100 | [diff] [blame] | 726 | if (pointerp(QueryProp(P_SWAP_CHANNELS))) |
MG Mud User | 88f1247 | 2016-06-24 23:31:02 +0200 | [diff] [blame] | 727 | SetProp(P_CHANNELS, QueryProp(P_SWAP_CHANNELS)); |
| 728 | else |
Arathorn | 78c0837 | 2019-12-11 20:14:23 +0100 | [diff] [blame] | 729 | SetProp(P_CHANNELS, m_indices(CHMASTER->list(ME))); |
Arathorn | 85de760 | 2019-11-28 23:04:03 +0100 | [diff] [blame] | 730 | |
| 731 | // <excl> enthaelt die Channelnamen, deren Channel nicht erstellt wurden. |
| 732 | string* excl = RegisterChannels(); |
Arathorn | 78c0837 | 2019-12-11 20:14:23 +0100 | [diff] [blame] | 733 | tell_object(ME,"Du schaltest folgende Ebenen ein:\n"+ |
| 734 | break_string(CountUp(QueryProp(P_CHANNELS) - excl), 78)); |
MG Mud User | 88f1247 | 2016-06-24 23:31:02 +0200 | [diff] [blame] | 735 | SetProp(P_SWAP_CHANNELS, 0); |
| 736 | return 1; |
| 737 | } |
Arathorn | 85de760 | 2019-11-28 23:04:03 +0100 | [diff] [blame] | 738 | |
| 739 | if (args == "aus") |
MG Mud User | 88f1247 | 2016-06-24 23:31:02 +0200 | [diff] [blame] | 740 | { |
| 741 | SetProp(P_SWAP_CHANNELS, QueryProp(P_CHANNELS)); |
| 742 | RemoveChannels(); |
| 743 | SetProp(P_CHANNELS, ({})); |
Arathorn | 78c0837 | 2019-12-11 20:14:23 +0100 | [diff] [blame] | 744 | tell_object(ME,"Du stellst die Ebenen ab.\n"); |
MG Mud User | 88f1247 | 2016-06-24 23:31:02 +0200 | [diff] [blame] | 745 | return 1; |
| 746 | } |
Arathorn | 85de760 | 2019-11-28 23:04:03 +0100 | [diff] [blame] | 747 | |
Arathorn | 0076469 | 2019-11-27 22:09:31 +0100 | [diff] [blame] | 748 | string* pa = old_explode(args, " "); |
Arathorn | 78c0837 | 2019-12-11 20:14:23 +0100 | [diff] [blame] | 749 | if (strstr("abkuerzungen", pa[0]) == 0) |
MG Mud User | 88f1247 | 2016-06-24 23:31:02 +0200 | [diff] [blame] | 750 | { |
Arathorn | 85de760 | 2019-11-28 23:04:03 +0100 | [diff] [blame] | 751 | string txt = ""; |
Arathorn | 78c0837 | 2019-12-11 20:14:23 +0100 | [diff] [blame] | 752 | if (sizeof(pa) > 1 && strstr("standard", pa[1]) == 0) |
MG Mud User | 88f1247 | 2016-06-24 23:31:02 +0200 | [diff] [blame] | 753 | { |
Arathorn | 78c0837 | 2019-12-11 20:14:23 +0100 | [diff] [blame] | 754 | tell_object(ME,"Die Standardabkuerzungen werden gesetzt.\n"); |
| 755 | SetProp(P_CHANNEL_SHORT, |
| 756 | DEFAULT_SHORTCUTS + (IS_LEARNER(ME) ? WIZARD_SHORTCUTS : ([]))); |
MG Mud User | 88f1247 | 2016-06-24 23:31:02 +0200 | [diff] [blame] | 757 | } |
Arathorn | 78c0837 | 2019-12-11 20:14:23 +0100 | [diff] [blame] | 758 | |
| 759 | mapping scut = QueryProp(P_CHANNEL_SHORT); |
| 760 | string* abbreviations = m_indices(scut); |
| 761 | foreach (string abk : sort_array(abbreviations, #'>)) |
| 762 | { |
| 763 | txt += sprintf("%5.5s = %s\n", abk, scut[abk]); |
Arathorn | dc28afc | 2018-11-26 22:20:59 +0100 | [diff] [blame] | 764 | } |
Arathorn | 78c0837 | 2019-12-11 20:14:23 +0100 | [diff] [blame] | 765 | More( "Folgende Abkuerzungen sind definiert:\n"+ |
| 766 | sprintf("%-78#s\n", txt) ); |
MG Mud User | 88f1247 | 2016-06-24 23:31:02 +0200 | [diff] [blame] | 767 | return 1; |
| 768 | } |
Arathorn | 85de760 | 2019-11-28 23:04:03 +0100 | [diff] [blame] | 769 | |
Arathorn | 78c0837 | 2019-12-11 20:14:23 +0100 | [diff] [blame] | 770 | if (strstr("standard", pa[0]) == 0) |
Arathorn | 85de760 | 2019-11-28 23:04:03 +0100 | [diff] [blame] | 771 | { |
| 772 | if (sizeof(pa) < 2) |
| 773 | { |
Arathorn | 78c0837 | 2019-12-11 20:14:23 +0100 | [diff] [blame] | 774 | notify_fail("Benutzung: ebene standard <Ebene>\n"+ |
| 775 | (QueryProp(P_STD_CHANNEL) |
| 776 | ? "Momentan ist '"+QueryProp(P_STD_CHANNEL)+"' eingestellt.\n" |
| 777 | : "Es ist keine Standardebene eingestellt.\n")); |
Arathorn | 85de760 | 2019-11-28 23:04:03 +0100 | [diff] [blame] | 778 | return 0; |
| 779 | } |
Arathorn | 78c0837 | 2019-12-11 20:14:23 +0100 | [diff] [blame] | 780 | |
| 781 | chans = CHMASTER->find(pa[1], ME); |
| 782 | if (!chans) |
Arathorn | 85de760 | 2019-11-28 23:04:03 +0100 | [diff] [blame] | 783 | { |
Arathorn | 78c0837 | 2019-12-11 20:14:23 +0100 | [diff] [blame] | 784 | notify_fail("Ebene '"+pa[1]+"' nicht gefunden!\n"); |
| 785 | return 0; |
Arathorn | 85de760 | 2019-11-28 23:04:03 +0100 | [diff] [blame] | 786 | } |
Arathorn | 78c0837 | 2019-12-11 20:14:23 +0100 | [diff] [blame] | 787 | else if (pointerp(chans)) |
| 788 | { |
| 789 | notify_fail( |
| 790 | "Das war keine eindeutige Angabe! Folgende Ebenen passen:\n"+ |
| 791 | break_string(CountUp(chans), 78)); |
| 792 | return 0; |
| 793 | } |
| 794 | |
| 795 | tell_object(ME,"'"+chans+"' ist jetzt die Standardebene.\n"); |
| 796 | SetProp(P_STD_CHANNEL, chans); |
| 797 | return 1; |
Arathorn | 85de760 | 2019-11-28 23:04:03 +0100 | [diff] [blame] | 798 | } |
MG Mud User | 88f1247 | 2016-06-24 23:31:02 +0200 | [diff] [blame] | 799 | return(0); |
| 800 | } |