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 | |
| 27 | #define P_SWAP_CHANNELS "swap_channels" |
| 28 | #define P_CHANNEL_SHORT "short_channels" |
| 29 | |
| 30 | #define CHANNELCMDS "[#@%$&()<>a-zA-Z0-9\\-]" |
| 31 | |
| 32 | #define DEFAULT_CHANNELS ({"Abenteuer", "Anfaenger","Grats","Tod", "ZT"}) |
| 33 | #define DEFAULT_SHORTCUTS \ |
| 34 | ([ \ |
| 35 | "b":"Abenteuer", \ |
| 36 | "a":"Allgemein", \ |
| 37 | "B":"Beileid", \ |
| 38 | "q":"D-chat", \ |
| 39 | "G":"Grats", \ |
| 40 | "M":"Moerder", \ |
| 41 | "h":"Seher", \ |
| 42 | "T":"Tod", \ |
| 43 | ]) |
| 44 | |
| 45 | #define WIZARD_SHORTCUTS \ |
| 46 | ([ \ |
| 47 | "P":"D-code", \ |
| 48 | "D":"Debug", \ |
| 49 | "O":"Intercode", \ |
| 50 | "I":"Intermud", \ |
| 51 | "m":"Magier", \ |
| 52 | ]) |
| 53 | |
| 54 | |
| 55 | private nosave mapping shortcut; |
| 56 | private nosave int c_status; |
| 57 | |
| 58 | void create() |
| 59 | { |
| 60 | Set(P_CHANNELS, SAVE, F_MODE); |
| 61 | Set(P_CHANNELS, DEFAULT_CHANNELS); |
| 62 | Set(P_SWAP_CHANNELS, SAVE, F_MODE); |
| 63 | Set(P_STD_CHANNEL, "Allgemein"); |
| 64 | Set(P_STD_CHANNEL, SAVE, F_MODE); |
| 65 | Set(P_CHANNEL_SHORT, SAVE, F_MODE); |
| 66 | Set(P_CHANNEL_SHORT, DEFAULT_SHORTCUTS |
| 67 | + (IS_LEARNER(this_object()) ? WIZARD_SHORTCUTS : ([]))); |
| 68 | } |
| 69 | |
Arathorn | 0076469 | 2019-11-27 22:09:31 +0100 | [diff] [blame] | 70 | static <int|string>** _query_localcmds() |
MG Mud User | 88f1247 | 2016-06-24 23:31:02 +0200 | [diff] [blame] | 71 | { |
| 72 | return ({({"-","ChannelParser", 1, 0}), |
| 73 | ({"ebene", "ChannelAdmin", 0, 0}), |
| 74 | ({"ebenen", "ChannelAdmin", 1, 0}), |
| 75 | }); |
| 76 | } |
| 77 | |
Arathorn | 0076469 | 2019-11-27 22:09:31 +0100 | [diff] [blame] | 78 | string* RegisterChannels() |
MG Mud User | 88f1247 | 2016-06-24 23:31:02 +0200 | [diff] [blame] | 79 | { |
Arathorn | 85de760 | 2019-11-28 23:04:03 +0100 | [diff] [blame] | 80 | if (extern_call() && |
| 81 | previous_object() != find_object(CHMASTER)) |
Zesstra | f1137e8 | 2019-11-27 23:37:30 +0100 | [diff] [blame] | 82 | return 0; |
| 83 | |
MG Mud User | 88f1247 | 2016-06-24 23:31:02 +0200 | [diff] [blame] | 84 | c_status = 0; |
| 85 | shortcut = QueryProp(P_CHANNEL_SHORT); |
Arathorn | 85de760 | 2019-11-28 23:04:03 +0100 | [diff] [blame] | 86 | SetProp(P_CHANNELS, map(QueryProp(P_CHANNELS) || ({}), #'lower_case)); |
| 87 | |
| 88 | closure cl = symbol_function("join", CHMASTER); |
| 89 | string* err; |
| 90 | if (closurep(cl)) |
| 91 | { |
| 92 | err = filter(QueryProp(P_CHANNELS), cl, this_object()); |
MG Mud User | 88f1247 | 2016-06-24 23:31:02 +0200 | [diff] [blame] | 93 | } |
Arathorn | 85de760 | 2019-11-28 23:04:03 +0100 | [diff] [blame] | 94 | if (QueryProp(P_LEVEL) < 5) |
| 95 | return err; |
| 96 | |
| 97 | // CHMASTER->new() gibt bei Erfolg 0 zurueck, d.h. es bleiben |
| 98 | // alle Elemente erhalten, deren Channel nicht erstellt werden konnten. |
| 99 | // Die werden an die Aufrufer zurueckgegeben. |
| 100 | return filter(err, CHMASTER, "new", this_object()); |
MG Mud User | 88f1247 | 2016-06-24 23:31:02 +0200 | [diff] [blame] | 101 | } |
| 102 | |
Arathorn | 0076469 | 2019-11-27 22:09:31 +0100 | [diff] [blame] | 103 | string* RemoveChannels() |
MG Mud User | 88f1247 | 2016-06-24 23:31:02 +0200 | [diff] [blame] | 104 | { |
Arathorn | 85de760 | 2019-11-28 23:04:03 +0100 | [diff] [blame] | 105 | if (extern_call() && |
| 106 | previous_object() != find_object(CHMASTER)) |
Zesstra | f1137e8 | 2019-11-27 23:37:30 +0100 | [diff] [blame] | 107 | return 0; |
| 108 | |
Arathorn | 85de760 | 2019-11-28 23:04:03 +0100 | [diff] [blame] | 109 | string* err = ({}); |
| 110 | |
| 111 | if (!c_status) |
| 112 | c_status = 1; |
| 113 | else |
| 114 | return err; |
| 115 | |
| 116 | closure cl = symbol_function("leave", CHMASTER); |
| 117 | if (closurep(cl)) |
| 118 | { |
| 119 | err = filter(QueryProp(P_CHANNELS), cl, this_object()); |
| 120 | SetProp(P_CHANNELS, QueryProp(P_CHANNELS) - err); |
MG Mud User | 88f1247 | 2016-06-24 23:31:02 +0200 | [diff] [blame] | 121 | } |
| 122 | return err; |
| 123 | } |
| 124 | |
Arathorn | 0076469 | 2019-11-27 22:09:31 +0100 | [diff] [blame] | 125 | varargs private string getName(string|object|closure x, int fall) { |
| 126 | string|object o = closurep(x) ? query_closure_object(x) : x; |
Arathorn | 85de760 | 2019-11-28 23:04:03 +0100 | [diff] [blame] | 127 | if (stringp(o) && sizeof(o) && (x = find_object(o))) |
MG Mud User | 88f1247 | 2016-06-24 23:31:02 +0200 | [diff] [blame] | 128 | o = x; |
Arathorn | 85de760 | 2019-11-28 23:04:03 +0100 | [diff] [blame] | 129 | |
MG Mud User | 88f1247 | 2016-06-24 23:31:02 +0200 | [diff] [blame] | 130 | // Objekte |
Arathorn | 85de760 | 2019-11-28 23:04:03 +0100 | [diff] [blame] | 131 | if (objectp(o)) |
| 132 | { |
MG Mud User | 88f1247 | 2016-06-24 23:31:02 +0200 | [diff] [blame] | 133 | // Magier sehen unsichtbare nicht nur als "Jemand" |
| 134 | if (o->QueryProp(P_INVIS) && IS_LEARNING(this_object())) |
| 135 | return "("+capitalize(getuid(o))+")"; |
| 136 | // Froesche mit Namen versorgen. |
| 137 | if (o->QueryProp(P_FROG)) |
| 138 | return "Frosch "+capitalize(getuid(o)); |
| 139 | // Default (Unsichtbare als "Jemand" (s. Name())) |
| 140 | return o->Name(fall, 2)||"<Unbekannt>"; |
| 141 | } |
| 142 | // Strings |
Arathorn | 85de760 | 2019-11-28 23:04:03 +0100 | [diff] [blame] | 143 | else if (stringp(o) && sizeof(o)) |
| 144 | { |
| 145 | if (o[0] == '/') |
| 146 | { |
MG Mud User | 88f1247 | 2016-06-24 23:31:02 +0200 | [diff] [blame] | 147 | // unsichtbare Objekte... |
| 148 | int p = strstr(o, "$"); |
Arathorn | 85de760 | 2019-11-28 23:04:03 +0100 | [diff] [blame] | 149 | if (p != -1) |
| 150 | { |
| 151 | // Magier im Magiermodus kriegen den Realnamen, andere nicht. |
| 152 | if (IS_LEARNING(this_object())) |
| 153 | return o[1..p-1]; |
| 154 | else |
| 155 | return o[p+1..]; |
MG Mud User | 88f1247 | 2016-06-24 23:31:02 +0200 | [diff] [blame] | 156 | } |
Arathorn | 85de760 | 2019-11-28 23:04:03 +0100 | [diff] [blame] | 157 | else // doch nicht unsichtbar |
| 158 | return (fall == WESSEN ? o+"s" : o); |
MG Mud User | 88f1247 | 2016-06-24 23:31:02 +0200 | [diff] [blame] | 159 | } |
| 160 | else |
| 161 | // nicht unsichtbar |
| 162 | return (fall == WESSEN ? o+"s" : o); |
| 163 | } |
| 164 | // Fall-through |
| 165 | return "<Unbekannt>"; |
| 166 | } |
| 167 | |
Arathorn | 69d6ddd | 2019-11-25 21:06:34 +0100 | [diff] [blame] | 168 | // <nonint> unterdrueckt die Ausgabe an den Spieler und liefert den Text |
Arathorn | 85de760 | 2019-11-28 23:04:03 +0100 | [diff] [blame] | 169 | // zurueck. Wird nur fuer die Ebenenhistory benutzt. |
Arathorn | 69d6ddd | 2019-11-25 21:06:34 +0100 | [diff] [blame] | 170 | string ChannelMessage(<string|object|int>* msg, int nonint) |
MG Mud User | 88f1247 | 2016-06-24 23:31:02 +0200 | [diff] [blame] | 171 | { |
| 172 | string channel_message; |
Arathorn | 85de760 | 2019-11-28 23:04:03 +0100 | [diff] [blame] | 173 | string channel = msg[0]; |
Arathorn | 69d6ddd | 2019-11-25 21:06:34 +0100 | [diff] [blame] | 174 | |
| 175 | // Wenn eine Ebenenmeldung ausgegeben werden soll, ist msg[1] ein Objekt, |
| 176 | // im Fall der History aber ein String. Daher wird <sender> als Union |
| 177 | // deklariert. Das ist unproblematisch, weil die beiden Datentypen |
| 178 | // komplett getrennte Wege nehmen: ein Objekt wird an ReceiveMsg() |
| 179 | // durchgereicht (Ebenenmeldung). Ein String wird direkt in die Meldung |
| 180 | // (History) eingebaut, diese an den ChannelParser() zurueckgegeben, der |
| 181 | // sie via More() ausgibt. |
Arathorn | 85de760 | 2019-11-28 23:04:03 +0100 | [diff] [blame] | 182 | string|object sender = msg[1]; |
| 183 | string message = msg[2]; |
MG Mud User | 88f1247 | 2016-06-24 23:31:02 +0200 | [diff] [blame] | 184 | int msg_type = msg[3]; |
| 185 | |
Arathorn | 85de760 | 2019-11-28 23:04:03 +0100 | [diff] [blame] | 186 | if (previous_object() != find_object(CHMASTER) && |
| 187 | previous_object() != ME ) |
| 188 | return 0; |
MG Mud User | 88f1247 | 2016-06-24 23:31:02 +0200 | [diff] [blame] | 189 | |
| 190 | string sender_name = getName(sender, msg_type == MSG_GEMOTE ? WESSEN : WER); |
Arathorn | 85de760 | 2019-11-28 23:04:03 +0100 | [diff] [blame] | 191 | int prepend_indent_flag = |
| 192 | QueryProp(P_MESSAGE_PREPEND) ? BS_PREPEND_INDENT : 0; |
| 193 | |
| 194 | switch (msg_type) |
| 195 | { |
| 196 | case MSG_EMPTY: |
| 197 | channel_message= message+"\n"; |
| 198 | break; |
| 199 | case MSG_GEMOTE: |
| 200 | case MSG_EMOTE: |
| 201 | channel_message = break_string(sender_name + " "+ message+"]", 78, |
| 202 | sprintf("[%s:", channel), |
| 203 | BS_INDENT_ONCE|prepend_indent_flag); |
| 204 | break; |
| 205 | case MSG_SAY: |
| 206 | default: |
| 207 | string presay=sprintf("[%s:%s] ", channel, sender_name); |
| 208 | channel_message = break_string(message, max(78,sizeof(presay)+10), |
| 209 | presay, prepend_indent_flag); |
| 210 | break; |
MG Mud User | 88f1247 | 2016-06-24 23:31:02 +0200 | [diff] [blame] | 211 | } |
Arathorn | 85de760 | 2019-11-28 23:04:03 +0100 | [diff] [blame] | 212 | |
| 213 | if (nonint) |
MG Mud User | 88f1247 | 2016-06-24 23:31:02 +0200 | [diff] [blame] | 214 | return channel_message; |
| 215 | |
| 216 | // Wenn GMCP sich um Uebertragung der Nachricht kuemmert, wird ReceiveMsg() |
Zesstra | 7ccec73 | 2019-01-06 22:10:09 +0100 | [diff] [blame] | 217 | // nicht mehr aufgerufen. getName leider nochmal aufrufen, weil GMCP den |
| 218 | // Namen im Nominativ braucht. |
| 219 | if (msg_type == MSG_GEMOTE) |
| 220 | sender_name = getName(sender, WER); |
MG Mud User | 88f1247 | 2016-06-24 23:31:02 +0200 | [diff] [blame] | 221 | if (GMCP_Channel(channel_message, channel, sender_name) != 1) |
| 222 | { |
| 223 | // Der Ebenenname muss in Kleinbuchstaben uebergeben werden, damit die |
| 224 | // Ignorierepruefung funktioniert. Die ignorierestrings sind naemlich alle |
| 225 | // kleingeschrieben. |
Arathorn | 85de760 | 2019-11-28 23:04:03 +0100 | [diff] [blame] | 226 | ReceiveMsg(channel_message, |
MG Mud User | 88f1247 | 2016-06-24 23:31:02 +0200 | [diff] [blame] | 227 | MT_COMM|MT_FAR|MSG_DONT_STORE|MSG_DONT_WRAP, |
| 228 | MA_CHANNEL"." + lower_case(channel), 0, sender); |
| 229 | } |
| 230 | return 0; |
| 231 | } |
| 232 | |
| 233 | private void createList(string n, mixed a, mixed m, mixed l) |
| 234 | { |
Arathorn | 0076469 | 2019-11-27 22:09:31 +0100 | [diff] [blame] | 235 | int pos = member(map(m_values(shortcut), #'lower_case/*'*/), n); |
| 236 | string sh = ""; |
Arathorn | 85de760 | 2019-11-28 23:04:03 +0100 | [diff] [blame] | 237 | if (pos != -1) |
MG Mud User | 88f1247 | 2016-06-24 23:31:02 +0200 | [diff] [blame] | 238 | sh = m_indices(shortcut)[pos]; |
Arathorn | 0076469 | 2019-11-27 22:09:31 +0100 | [diff] [blame] | 239 | |
| 240 | string* mem=map(a[I_MEMBER],#'getName/*'*/, WER); |
Arathorn | 85de760 | 2019-11-28 23:04:03 +0100 | [diff] [blame] | 241 | mem -= ({"<MasteR>"}); |
MG Mud User | 88f1247 | 2016-06-24 23:31:02 +0200 | [diff] [blame] | 242 | l += ({ sprintf("%-12.12'.'s %c[%-1.1s] %|12.12' 's (%-|3' 'd) %-42.42s\n", |
Arathorn | 85de760 | 2019-11-28 23:04:03 +0100 | [diff] [blame] | 243 | a[I_NAME], (member(m, n) != -1 ? '*' : ' '), sh, |
| 244 | a[I_MASTER] ? |
| 245 | getName(a[I_MASTER]) : getName(a[I_ACCESS]), |
| 246 | sizeof(mem), |
| 247 | (closurep(a[I_INFO]) && objectp(query_closure_object(a[I_INFO]))) ? |
| 248 | funcall(a[I_INFO]) || "- Keine Beschreibung -" : |
| 249 | (stringp(a[I_INFO]) ? a[I_INFO] : "- Keine Beschreibung -") |
| 250 | ) }); |
MG Mud User | 88f1247 | 2016-06-24 23:31:02 +0200 | [diff] [blame] | 251 | } |
| 252 | |
| 253 | private mixed getChannel(string ch) |
| 254 | { |
Arathorn | 85de760 | 2019-11-28 23:04:03 +0100 | [diff] [blame] | 255 | if (!sizeof(ch)) |
Arathorn | 0076469 | 2019-11-27 22:09:31 +0100 | [diff] [blame] | 256 | ch = QueryProp(P_STD_CHANNEL); |
Arathorn | 85de760 | 2019-11-28 23:04:03 +0100 | [diff] [blame] | 257 | if (shortcut && shortcut[ch]) |
Arathorn | 0076469 | 2019-11-27 22:09:31 +0100 | [diff] [blame] | 258 | ch = shortcut[ch]; |
MG Mud User | 88f1247 | 2016-06-24 23:31:02 +0200 | [diff] [blame] | 259 | return CHMASTER->find(ch, this_object()); |
| 260 | } |
| 261 | |
| 262 | #ifndef DEBUG |
Arathorn | 85de760 | 2019-11-28 23:04:03 +0100 | [diff] [blame] | 263 | #define DEBUG(x) if (funcall(symbol_function('find_player),"zesstra"))\ |
MG Mud User | 88f1247 | 2016-06-24 23:31:02 +0200 | [diff] [blame] | 264 | tell_object(funcall(symbol_function('find_player),"zesstra"),\ |
Zesstra | 57a693e | 2019-01-06 22:08:24 +0100 | [diff] [blame] | 265 | "MDBG: "+x+"\n") |
MG Mud User | 88f1247 | 2016-06-24 23:31:02 +0200 | [diff] [blame] | 266 | #endif |
Arathorn | 85de760 | 2019-11-28 23:04:03 +0100 | [diff] [blame] | 267 | |
MG Mud User | 88f1247 | 2016-06-24 23:31:02 +0200 | [diff] [blame] | 268 | int ChannelParser(string args) |
| 269 | { |
Arathorn | 6d46564 | 2019-11-25 21:06:07 +0100 | [diff] [blame] | 270 | mixed ch; |
MG Mud User | 88f1247 | 2016-06-24 23:31:02 +0200 | [diff] [blame] | 271 | int pos, type, err; |
Arathorn | 6d46564 | 2019-11-25 21:06:07 +0100 | [diff] [blame] | 272 | string txt, tmp; |
| 273 | string|string* cmd = query_verb(); |
MG Mud User | 88f1247 | 2016-06-24 23:31:02 +0200 | [diff] [blame] | 274 | args = _unparsed_args(); |
| 275 | notify_fail("Benutzung: -<Ebene>[ ]['|:|;]<Text>\n" |
| 276 | " -<Ebene>[+|-|?|!|*]\n" |
| 277 | " -?\n"); |
Arathorn | 85de760 | 2019-11-28 23:04:03 +0100 | [diff] [blame] | 278 | if (!cmd && !args) |
| 279 | return 0; |
| 280 | |
| 281 | if (!args) |
| 282 | args = ""; |
| 283 | |
MG Mud User | 88f1247 | 2016-06-24 23:31:02 +0200 | [diff] [blame] | 284 | cmd = cmd[1..]; |
Arathorn | 85de760 | 2019-11-28 23:04:03 +0100 | [diff] [blame] | 285 | cmd = regexplode(cmd, "^" CHANNELCMDS "*" "([+-]|\\!|\\?|\\*)*") |
| 286 | if (sizeof(cmd) > 1) |
MG Mud User | 88f1247 | 2016-06-24 23:31:02 +0200 | [diff] [blame] | 287 | { |
| 288 | //z.B. cmd= ({"","allgemein",":testet"}) |
Arathorn | 85de760 | 2019-11-28 23:04:03 +0100 | [diff] [blame] | 289 | if (sizeof(cmd[1]) > 1 && strstr("+-?!*", cmd[1][<1..<1]) > -1) |
MG Mud User | 88f1247 | 2016-06-24 23:31:02 +0200 | [diff] [blame] | 290 | tmp = cmd[1][0..<2]; |
| 291 | else |
| 292 | tmp = cmd[1]; |
Arathorn | 85de760 | 2019-11-28 23:04:03 +0100 | [diff] [blame] | 293 | |
| 294 | if (cmd[1] != "?" && cmd[1] != "!") |
Zesstra | 57a693e | 2019-01-06 22:08:24 +0100 | [diff] [blame] | 295 | { |
| 296 | ch = getChannel(tmp); |
Arathorn | 85de760 | 2019-11-28 23:04:03 +0100 | [diff] [blame] | 297 | if (pointerp(ch)) |
MG Mud User | 88f1247 | 2016-06-24 23:31:02 +0200 | [diff] [blame] | 298 | { |
| 299 | notify_fail("Diese Angabe war nicht eindeutig! " |
| 300 | "Folgende Ebenen passen:\n" |
| 301 | +implode(ch, ", ")+"\n"); |
| 302 | return 0; |
| 303 | } |
Arathorn | 85de760 | 2019-11-28 23:04:03 +0100 | [diff] [blame] | 304 | else if (!ch) |
| 305 | { |
| 306 | notify_fail("Die Ebene '"+tmp+ "' gibt es nicht!\n"); |
| 307 | return 0; |
| 308 | } |
Zesstra | 57a693e | 2019-01-06 22:08:24 +0100 | [diff] [blame] | 309 | } |
Arathorn | 85de760 | 2019-11-28 23:04:03 +0100 | [diff] [blame] | 310 | |
MG Mud User | 88f1247 | 2016-06-24 23:31:02 +0200 | [diff] [blame] | 311 | if (sizeof(cmd[1])) { |
Arathorn | 85de760 | 2019-11-28 23:04:03 +0100 | [diff] [blame] | 312 | switch (cmd[1][<1]) { |
| 313 | case '+': |
| 314 | switch (CHMASTER->join(ch, this_object())) |
| 315 | { |
| 316 | case E_ACCESS_DENIED: |
| 317 | notify_fail("Du darfst an die Ebene '"+ch+"' nicht heran.\n"); |
| 318 | return 0; |
| 319 | case E_ALREADY_JOINED: |
| 320 | notify_fail("Du hast diese Ebene schon betreten!\n"); |
| 321 | return 0; |
| 322 | default: |
| 323 | break; |
| 324 | } |
| 325 | write("Du betrittst die Ebene '"+ch+"'.\n"); |
| 326 | if (member(QueryProp(P_CHANNELS), ch = lower_case(ch)) == -1) |
| 327 | SetProp(P_CHANNELS, QueryProp(P_CHANNELS) + ({ ch })); |
| 328 | return 1; |
| 329 | |
| 330 | case '-': |
| 331 | switch (CHMASTER->leave(ch, this_object())) |
| 332 | { |
| 333 | case E_ACCESS_DENIED: |
| 334 | write("Du kannst die Ebene '"+ch+"' nicht verlassen.\n"); |
| 335 | break; |
| 336 | case E_NOT_MEMBER: |
| 337 | write("Wie willst Du eine Ebene verlassen, welche Du nicht " |
| 338 | "betreten hast?\n"); |
| 339 | break; |
| 340 | default: |
| 341 | write("Du verlaesst die Ebene '"+ch+"'.\n"); |
| 342 | SetProp(P_CHANNELS, |
| 343 | QueryProp(P_CHANNELS) - ({ lower_case(ch), ch })); |
| 344 | break; |
| 345 | } |
| 346 | return 1; |
| 347 | |
| 348 | case '!': |
| 349 | case '?': |
| 350 | mapping l; |
| 351 | if (mappingp(l = CHMASTER->list(this_object()))) |
| 352 | { |
| 353 | if (stringp(ch) && sizeof(ch) && pointerp(l[ch = lower_case(ch)])) |
| 354 | { |
| 355 | int c; object o; string n; string *m; |
| 356 | m = sort_array( |
| 357 | map(l[ch][I_MEMBER],#'getName/*'*/, WER), |
| 358 | #'>/*'*/); |
| 359 | m-=({"<MasteR>"}); |
| 360 | write(l[ch][I_NAME]+", "+funcall(l[ch][I_INFO])+".\n"); |
| 361 | write("Du siehst "+((c = sizeof(m)) > 0 |
| 362 | ? (c == 1 ? "ein Gesicht" : c+" Gesichter") |
| 363 | : "niemanden")+" auf der Ebene '" |
| 364 | +l[ch][I_NAME]+"':\n"); |
| 365 | write(break_string(implode(m,", "), 78)); |
| 366 | write((l[ch][I_MASTER] ? |
| 367 | getName(l[ch][I_MASTER]) : getName(l[ch][I_ACCESS], WER)) |
| 368 | +" hat das Sagen auf dieser Ebene.\n"); |
| 369 | } |
| 370 | else |
| 371 | { |
| 372 | string* list = ({}); |
| 373 | if (cmd[1][<1] == '!') |
| 374 | l -= mkmapping(m_indices(l) - QueryProp(P_CHANNELS)); |
| 375 | walk_mapping(l, #'createList/*'*/, QueryProp(P_CHANNELS), &list); |
| 376 | list = sort_array(list, #'>/*'*/); |
| 377 | txt = sprintf("%-12.12' 's [A] %|12' 's (%-3' 's) %-42.42s\n", |
| 378 | "Name", "Eigner", "Sp", "Beschreibung") |
| 379 | + "-------------------------------------------------------" |
| 380 | + "-----------------------\n" |
| 381 | + implode(list, ""); |
| 382 | More(txt); |
| 383 | } |
| 384 | } |
| 385 | return 1; |
| 386 | |
| 387 | case '*': |
| 388 | mixed hist = CHMASTER->history(ch, this_object()); |
| 389 | if (!pointerp(hist) || !sizeof(hist)) |
| 390 | { |
| 391 | write("Es ist keine Geschichte fuer '"+ch+"' verfuegbar.\n"); |
| 392 | return 1; |
| 393 | } |
| 394 | |
| 395 | //(Zesstra) cmd hat offenbar immer 3 Elemente... |
| 396 | //bei -all* ({"","all*",""}) |
| 397 | //bei -all*10 ({"","all*,"10"}) |
| 398 | //also ist bei -all* amount immer == 0 und es funktioniert eher |
| 399 | //zufaellig. |
| 400 | /*if(sizeof(cmd) > 2) |
| 401 | amount = to_int(cmd[2]); |
| 402 | else |
| 403 | amount=sizeof(hist);*/ |
| 404 | int amount = to_int(cmd[2]); |
| 405 | if (amount <= 0 || amount >= sizeof(hist)) |
| 406 | amount = sizeof(hist); |
| 407 | |
| 408 | txt = "Folgendes ist auf '"+ch+"' passiert:\n" |
| 409 | + implode(map(hist[<amount..], #'ChannelMessage/*'*/, 1), ""); |
MG Mud User | 88f1247 | 2016-06-24 23:31:02 +0200 | [diff] [blame] | 410 | More(txt); |
Arathorn | 85de760 | 2019-11-28 23:04:03 +0100 | [diff] [blame] | 411 | return 1; |
| 412 | |
| 413 | default: |
| 414 | break; |
Zesstra | 57a693e | 2019-01-06 22:08:24 +0100 | [diff] [blame] | 415 | } |
MG Mud User | 88f1247 | 2016-06-24 23:31:02 +0200 | [diff] [blame] | 416 | } |
| 417 | } |
Arathorn | 85de760 | 2019-11-28 23:04:03 +0100 | [diff] [blame] | 418 | |
| 419 | if (sizeof(cmd = implode(cmd[2..], ""))) |
| 420 | args = cmd + (sizeof(args) ? " " : "") + args; |
MG Mud User | 88f1247 | 2016-06-24 23:31:02 +0200 | [diff] [blame] | 421 | |
| 422 | // KOntrollchars ausfiltern. |
| 423 | args = regreplace(args,"[[:cntrl:]]","",RE_PCRE|RE_GLOBAL); |
Arathorn | 85de760 | 2019-11-28 23:04:03 +0100 | [diff] [blame] | 424 | if (!sizeof(args)) |
| 425 | return 0; |
MG Mud User | 88f1247 | 2016-06-24 23:31:02 +0200 | [diff] [blame] | 426 | |
| 427 | //Wenn cmd leer ist: MSG_SAY |
Arathorn | 85de760 | 2019-11-28 23:04:03 +0100 | [diff] [blame] | 428 | if (!sizeof(cmd)) |
| 429 | type = MSG_SAY; |
| 430 | else |
| 431 | { |
| 432 | switch (cmd[0]) |
MG Mud User | 88f1247 | 2016-06-24 23:31:02 +0200 | [diff] [blame] | 433 | { |
Arathorn | 85de760 | 2019-11-28 23:04:03 +0100 | [diff] [blame] | 434 | case ':' : |
| 435 | type = MSG_EMOTE; |
| 436 | args = args[1..]; |
| 437 | break; |
| 438 | case ';' : |
| 439 | type = MSG_GEMOTE; |
| 440 | args = args[1..]; |
| 441 | break; |
| 442 | case '\'': |
| 443 | args = args[1..]; |
| 444 | // Der Fallthrough in default ist hier Absicht. |
| 445 | default : |
| 446 | type = MSG_SAY; |
| 447 | break; |
MG Mud User | 88f1247 | 2016-06-24 23:31:02 +0200 | [diff] [blame] | 448 | } |
| 449 | } |
Arathorn | 85de760 | 2019-11-28 23:04:03 +0100 | [diff] [blame] | 450 | |
| 451 | if (!ch || !sizeof(ch)) |
| 452 | ch = QueryProp(P_STD_CHANNEL); |
| 453 | |
| 454 | err = CHMASTER->send(ch, this_object(), args, type); |
| 455 | if (err < 0) |
| 456 | { |
| 457 | err = CHMASTER->join(ch, this_object()); |
| 458 | if (!err) |
MG Mud User | 88f1247 | 2016-06-24 23:31:02 +0200 | [diff] [blame] | 459 | { |
Arathorn | 85de760 | 2019-11-28 23:04:03 +0100 | [diff] [blame] | 460 | if (member(QueryProp(P_CHANNELS), ch = lower_case(ch)) == -1) |
MG Mud User | 88f1247 | 2016-06-24 23:31:02 +0200 | [diff] [blame] | 461 | SetProp(P_CHANNELS, QueryProp(P_CHANNELS) + ({ ch })); |
| 462 | err = CHMASTER->send(ch, this_object(), args, type); |
| 463 | } |
Arathorn | 85de760 | 2019-11-28 23:04:03 +0100 | [diff] [blame] | 464 | } |
MG Mud User | 88f1247 | 2016-06-24 23:31:02 +0200 | [diff] [blame] | 465 | |
Arathorn | 85de760 | 2019-11-28 23:04:03 +0100 | [diff] [blame] | 466 | switch (err) |
MG Mud User | 88f1247 | 2016-06-24 23:31:02 +0200 | [diff] [blame] | 467 | { |
Arathorn | 85de760 | 2019-11-28 23:04:03 +0100 | [diff] [blame] | 468 | case E_ACCESS_DENIED: |
| 469 | notify_fail("Auf der Ebene '"+ch+"' darfst Du nichts sagen.\n"); |
| 470 | return 0; |
| 471 | case E_NOT_MEMBER: |
| 472 | notify_fail("Du hast die Ebene '"+ch+"' nicht betreten!\n"); |
| 473 | return 0; |
MG Mud User | 88f1247 | 2016-06-24 23:31:02 +0200 | [diff] [blame] | 474 | } |
| 475 | return 1; |
| 476 | } |
| 477 | |
| 478 | int ChannelAdmin(string args) |
| 479 | { |
Arathorn | 85de760 | 2019-11-28 23:04:03 +0100 | [diff] [blame] | 480 | args = _unparsed_args(); |
| 481 | |
MG Mud User | 88f1247 | 2016-06-24 23:31:02 +0200 | [diff] [blame] | 482 | string n, descr, sh, cn; |
Arathorn | 0076469 | 2019-11-27 22:09:31 +0100 | [diff] [blame] | 483 | mixed tmp; |
MG Mud User | 88f1247 | 2016-06-24 23:31:02 +0200 | [diff] [blame] | 484 | notify_fail("Benutzung: ebene <Abkuerzung>=<Ebene>\n" |
| 485 | " ebene <Abkuerzung>=\n" |
| 486 | " ebene abkuerzungen [standard]\n" |
| 487 | " ebene standard <Ebene>\n" |
| 488 | " ebene an|ein|aus\n" |
| 489 | +(QueryProp(P_LEVEL) >= 5 ? |
| 490 | " ebene neu <Name> <Bezeichnung>\n" |
Arathorn | 85de760 | 2019-11-28 23:04:03 +0100 | [diff] [blame] | 491 | " ebene beschreibung <Name> <Beschreibung>\n" : "") |
| 492 | +(IS_ARCH(this_object()) ? |
| 493 | " ebene kill <Name>\n" |
| 494 | " ebene clear <Name>\n": "")); |
| 495 | |
| 496 | if (!args || !sizeof(args)) |
| 497 | return 0; |
| 498 | |
| 499 | if (sscanf(args, "kill %s", n) && IS_ARCH(this_object())) |
MG Mud User | 88f1247 | 2016-06-24 23:31:02 +0200 | [diff] [blame] | 500 | { |
Arathorn | 85de760 | 2019-11-28 23:04:03 +0100 | [diff] [blame] | 501 | cn = CHMASTER->find(n, this_object()); |
| 502 | if (!cn) |
| 503 | cn = n; |
| 504 | |
| 505 | if (CHMASTER->remove(cn, this_object()) == E_ACCESS_DENIED) { |
| 506 | notify_fail("Die Ebene '"+cn+"' liess sich nicht entfernen!\n"); |
| 507 | return 0; |
MG Mud User | 88f1247 | 2016-06-24 23:31:02 +0200 | [diff] [blame] | 508 | } |
Arathorn | 85de760 | 2019-11-28 23:04:03 +0100 | [diff] [blame] | 509 | |
MG Mud User | 88f1247 | 2016-06-24 23:31:02 +0200 | [diff] [blame] | 510 | write("Du entfernst die Ebene '"+cn+"'.\n"); |
| 511 | return 1; |
| 512 | } |
Arathorn | 85de760 | 2019-11-28 23:04:03 +0100 | [diff] [blame] | 513 | |
| 514 | if (sscanf(args, "clear %s", n) && IS_ARCH(this_object())) |
MG Mud User | 88f1247 | 2016-06-24 23:31:02 +0200 | [diff] [blame] | 515 | { |
Arathorn | 85de760 | 2019-11-28 23:04:03 +0100 | [diff] [blame] | 516 | cn = CHMASTER->find(n, this_object()); |
| 517 | if (!cn) |
| 518 | cn = n; |
| 519 | |
| 520 | if (CHMASTER->clear_history(cn, this_object()) == E_ACCESS_DENIED) { |
| 521 | notify_fail("Der Verlauf zur Ebene '"+cn+"' liess sich nicht " |
| 522 | "entfernen!\n"); |
| 523 | return 0; |
MG Mud User | 88f1247 | 2016-06-24 23:31:02 +0200 | [diff] [blame] | 524 | } |
Arathorn | 85de760 | 2019-11-28 23:04:03 +0100 | [diff] [blame] | 525 | |
MG Mud User | 88f1247 | 2016-06-24 23:31:02 +0200 | [diff] [blame] | 526 | write("Du entfernst den Verlauf zur Ebene '"+cn+"'.\n"); |
| 527 | return 1; |
| 528 | } |
Arathorn | 85de760 | 2019-11-28 23:04:03 +0100 | [diff] [blame] | 529 | |
| 530 | if (sscanf(args, "neu %s %s", n, descr) == 2) |
MG Mud User | 88f1247 | 2016-06-24 23:31:02 +0200 | [diff] [blame] | 531 | { |
Arathorn | 85de760 | 2019-11-28 23:04:03 +0100 | [diff] [blame] | 532 | if (QueryProp(P_LEVEL) < 5) |
MG Mud User | 88f1247 | 2016-06-24 23:31:02 +0200 | [diff] [blame] | 533 | { |
Arathorn | 85de760 | 2019-11-28 23:04:03 +0100 | [diff] [blame] | 534 | notify_fail("Neue Ebenen zu erstellen, ist Dir verwehrt.\n"); |
| 535 | return 0; |
MG Mud User | 88f1247 | 2016-06-24 23:31:02 +0200 | [diff] [blame] | 536 | } |
Arathorn | 85de760 | 2019-11-28 23:04:03 +0100 | [diff] [blame] | 537 | |
| 538 | if (!sizeof(regexp(({ n }), "^" CHANNELCMDS CHANNELCMDS "*"))) |
| 539 | { |
| 540 | notify_fail("Der Name '"+n+"' ist nicht konform!\n"); |
| 541 | return 0; |
| 542 | } |
| 543 | |
| 544 | if (sizeof(n) > 20 ) |
| 545 | { |
| 546 | notify_fail("Der Name '"+n+"' ist zu lang.\n"); |
| 547 | return 0; |
| 548 | } |
| 549 | |
| 550 | if (CHMASTER->new(n, this_object(), descr) == E_ACCESS_DENIED) { |
| 551 | notify_fail("Diese Ebene darfst du nicht erschaffen!\n"); |
| 552 | return 0; |
| 553 | } |
| 554 | write("Du erschaffst die Ebene '"+n+"'.\n"); |
| 555 | SetProp(P_CHANNELS, QueryProp(P_CHANNELS) + ({ lower_case(n) })); |
| 556 | return 1; |
MG Mud User | 88f1247 | 2016-06-24 23:31:02 +0200 | [diff] [blame] | 557 | } |
Arathorn | 85de760 | 2019-11-28 23:04:03 +0100 | [diff] [blame] | 558 | |
| 559 | if (sscanf(args, "beschreibung %s %s", n, descr) == 2) |
MG Mud User | 88f1247 | 2016-06-24 23:31:02 +0200 | [diff] [blame] | 560 | { |
MG Mud User | 88f1247 | 2016-06-24 23:31:02 +0200 | [diff] [blame] | 561 | cn = CHMASTER->find(n, this_object()); |
Arathorn | 85de760 | 2019-11-28 23:04:03 +0100 | [diff] [blame] | 562 | if (!cn || pointerp(cn)) |
| 563 | { |
| 564 | notify_fail("Die Ebene '"+n+"' existiert nicht oder die Angabe " |
| 565 | "war nicht eindeutig.\n"); |
| 566 | return 0; |
| 567 | } |
| 568 | |
| 569 | mixed ch = CHMASTER->list(this_object()); |
| 570 | if (ch[lower_case(cn)][I_MASTER] != this_object()) |
| 571 | { |
| 572 | notify_fail("Du bist nicht berechtigt, die Beschreibung der Ebene" |
| 573 | " '"+cn+"' zu aendern.\n"); |
| 574 | return 0; |
| 575 | } |
MG Mud User | 88f1247 | 2016-06-24 23:31:02 +0200 | [diff] [blame] | 576 | ch[lower_case(cn)][I_INFO] = descr; |
| 577 | write("Die Ebene '"+cn+"' hat ab sofort die Beschreibung:\n"+descr+"\n"); |
| 578 | return 1; |
| 579 | } |
Arathorn | 85de760 | 2019-11-28 23:04:03 +0100 | [diff] [blame] | 580 | |
| 581 | if sscanf(args, "%s=%s", sh, n) == 2 && sizeof(n)) |
MG Mud User | 88f1247 | 2016-06-24 23:31:02 +0200 | [diff] [blame] | 582 | { |
Arathorn | 85de760 | 2019-11-28 23:04:03 +0100 | [diff] [blame] | 583 | tmp = CHMASTER->find(n, this_object()); |
| 584 | if (pointerp(tmp) || !tmp) |
| 585 | { |
| 586 | notify_fail("Benutzung: ebene <Abkuerzung>=<Ebene>\n"+ |
| 587 | (pointerp(tmp) ? |
| 588 | implode(tmp, ", ") + "\n" : |
| 589 | "Ebene '"+n+"' nicht gefunden!\n")); |
| 590 | return 0; |
| 591 | } |
| 592 | |
| 593 | mapping sc = QueryProp(P_CHANNEL_SHORT) || ([]); |
| 594 | m_add(sc, sh, tmp); |
MG Mud User | 88f1247 | 2016-06-24 23:31:02 +0200 | [diff] [blame] | 595 | SetProp(P_CHANNEL_SHORT, sc); |
Arathorn | 85de760 | 2019-11-28 23:04:03 +0100 | [diff] [blame] | 596 | |
MG Mud User | 88f1247 | 2016-06-24 23:31:02 +0200 | [diff] [blame] | 597 | shortcut = QueryProp(P_CHANNEL_SHORT); |
Arathorn | 85de760 | 2019-11-28 23:04:03 +0100 | [diff] [blame] | 598 | |
MG Mud User | 88f1247 | 2016-06-24 23:31:02 +0200 | [diff] [blame] | 599 | write("'"+sh+"' wird jetzt als Abkuerzung fuer '"+tmp+"' anerkannt.\n"); |
| 600 | return 1; |
| 601 | } |
Arathorn | 85de760 | 2019-11-28 23:04:03 +0100 | [diff] [blame] | 602 | |
| 603 | if (sscanf(args, "%s=", sh)) |
MG Mud User | 88f1247 | 2016-06-24 23:31:02 +0200 | [diff] [blame] | 604 | { |
Arathorn | 85de760 | 2019-11-28 23:04:03 +0100 | [diff] [blame] | 605 | SetProp(P_CHANNEL_SHORT, |
| 606 | m_copy_delete(QueryProp(P_CHANNEL_SHORT) || ([]), sh)); |
MG Mud User | 88f1247 | 2016-06-24 23:31:02 +0200 | [diff] [blame] | 607 | shortcut = QueryProp(P_CHANNEL_SHORT); |
| 608 | write("Du loeschst die Abkuerzung '"+sh+"'.\n"); |
| 609 | return 1; |
| 610 | } |
Arathorn | 85de760 | 2019-11-28 23:04:03 +0100 | [diff] [blame] | 611 | |
| 612 | if (args == "an" || args == "ein") |
MG Mud User | 88f1247 | 2016-06-24 23:31:02 +0200 | [diff] [blame] | 613 | { |
Arathorn | 85de760 | 2019-11-28 23:04:03 +0100 | [diff] [blame] | 614 | if (pointerp(QueryProp(P_SWAP_CHANNELS))) |
MG Mud User | 88f1247 | 2016-06-24 23:31:02 +0200 | [diff] [blame] | 615 | SetProp(P_CHANNELS, QueryProp(P_SWAP_CHANNELS)); |
| 616 | else |
| 617 | SetProp(P_CHANNELS, m_indices(CHMASTER->list(this_object()))); |
Arathorn | 85de760 | 2019-11-28 23:04:03 +0100 | [diff] [blame] | 618 | |
| 619 | // <excl> enthaelt die Channelnamen, deren Channel nicht erstellt wurden. |
| 620 | string* excl = RegisterChannels(); |
| 621 | write("Du schaltest folgende Ebenen ein:\n"+ |
| 622 | break_string(implode(QueryProp(P_CHANNELS) - excl, ", "), 78)); |
MG Mud User | 88f1247 | 2016-06-24 23:31:02 +0200 | [diff] [blame] | 623 | SetProp(P_SWAP_CHANNELS, 0); |
| 624 | return 1; |
| 625 | } |
Arathorn | 85de760 | 2019-11-28 23:04:03 +0100 | [diff] [blame] | 626 | |
| 627 | if (args == "aus") |
MG Mud User | 88f1247 | 2016-06-24 23:31:02 +0200 | [diff] [blame] | 628 | { |
| 629 | SetProp(P_SWAP_CHANNELS, QueryProp(P_CHANNELS)); |
| 630 | RemoveChannels(); |
| 631 | SetProp(P_CHANNELS, ({})); |
| 632 | write("Du stellst die Ebenen ab.\n"); |
| 633 | return 1; |
| 634 | } |
Arathorn | 85de760 | 2019-11-28 23:04:03 +0100 | [diff] [blame] | 635 | |
Arathorn | 0076469 | 2019-11-27 22:09:31 +0100 | [diff] [blame] | 636 | string* pa = old_explode(args, " "); |
Arathorn | 85de760 | 2019-11-28 23:04:03 +0100 | [diff] [blame] | 637 | if (!strstr("abkuerzungen", pa[0])) |
MG Mud User | 88f1247 | 2016-06-24 23:31:02 +0200 | [diff] [blame] | 638 | { |
Arathorn | 85de760 | 2019-11-28 23:04:03 +0100 | [diff] [blame] | 639 | string txt = ""; |
| 640 | if (sizeof(pa) > 1 && !strstr("standard", pa[1])) |
MG Mud User | 88f1247 | 2016-06-24 23:31:02 +0200 | [diff] [blame] | 641 | { |
Arathorn | 85de760 | 2019-11-28 23:04:03 +0100 | [diff] [blame] | 642 | write("Die Standardabkuerzungen werden gesetzt.\n"); |
MG Mud User | 88f1247 | 2016-06-24 23:31:02 +0200 | [diff] [blame] | 643 | SetProp(P_CHANNEL_SHORT, DEFAULT_SHORTCUTS |
| 644 | + (IS_LEARNER(this_object()) ? WIZARD_SHORTCUTS : ([]))); |
| 645 | } |
Arathorn | 85de760 | 2019-11-28 23:04:03 +0100 | [diff] [blame] | 646 | foreach (string abk, string ch_name : QueryProp(P_CHANNEL_SHORT)) { |
Arathorn | dc28afc | 2018-11-26 22:20:59 +0100 | [diff] [blame] | 647 | txt += sprintf("%5.5s = %s\n", abk, ch_name); |
| 648 | } |
MG Mud User | 88f1247 | 2016-06-24 23:31:02 +0200 | [diff] [blame] | 649 | txt = sprintf("Folgende Abkuerzungen sind definiert:\n%-78#s\n", |
Arathorn | 85de760 | 2019-11-28 23:04:03 +0100 | [diff] [blame] | 650 | implode(sort_array(old_explode(txt, "\n"), #'>/*'*/), "\n")); |
MG Mud User | 88f1247 | 2016-06-24 23:31:02 +0200 | [diff] [blame] | 651 | More(txt); |
| 652 | return 1; |
| 653 | } |
Arathorn | 85de760 | 2019-11-28 23:04:03 +0100 | [diff] [blame] | 654 | |
| 655 | if (!strstr("standard", pa[0])) |
| 656 | { |
| 657 | if (sizeof(pa) < 2) |
| 658 | { |
| 659 | notify_fail("Benutzung: ebene standard <Ebene>\n" |
| 660 | +(QueryProp(P_STD_CHANNEL) ? |
| 661 | "Momentan ist '"+QueryProp(P_STD_CHANNEL)+ |
| 662 | "' eingestellt.\n" : |
| 663 | "Es ist keine Standardebene eingestellt.\n")); |
| 664 | return 0; |
| 665 | } |
MG Mud User | 88f1247 | 2016-06-24 23:31:02 +0200 | [diff] [blame] | 666 | else |
Arathorn | 85de760 | 2019-11-28 23:04:03 +0100 | [diff] [blame] | 667 | { |
| 668 | tmp = CHMASTER->find(pa[1], this_object()); |
| 669 | if (pointerp(tmp)) |
| 670 | { |
| 671 | notify_fail("Das war keine eindeutige Angabe! " |
| 672 | "Folgende Ebenen passen:\n"+ |
| 673 | break_string(implode(tmp, ", "), 78)); |
| 674 | return 0; |
| 675 | } |
MG Mud User | 88f1247 | 2016-06-24 23:31:02 +0200 | [diff] [blame] | 676 | else |
Arathorn | 85de760 | 2019-11-28 23:04:03 +0100 | [diff] [blame] | 677 | { |
| 678 | if (!tmp) |
| 679 | { |
| 680 | notify_fail("Ebene '"+pa[1]+"' nicht gefunden!\n"); |
| 681 | return 0; |
| 682 | } |
MG Mud User | 88f1247 | 2016-06-24 23:31:02 +0200 | [diff] [blame] | 683 | else |
| 684 | { |
| 685 | write("'"+tmp+"' ist jetzt die Standardebene.\n"); |
| 686 | SetProp(P_STD_CHANNEL, tmp); |
| 687 | return 1; |
| 688 | } |
Arathorn | 85de760 | 2019-11-28 23:04:03 +0100 | [diff] [blame] | 689 | } |
| 690 | } |
| 691 | } |
MG Mud User | 88f1247 | 2016-06-24 23:31:02 +0200 | [diff] [blame] | 692 | return(0); |
| 693 | } |
| 694 | |