00001
00002
00003
00004
00005 #include "copyright.h"
00006 #include "config.h"
00007
00008 #include "config.h"
00009 #include "db.h"
00010 #include "mudconf.h"
00011 #include "externs.h"
00012 #include "match.h"
00013 #include "attrs.h"
00014 #include "powers.h"
00015
00016 #define CON_LOCAL 0x01
00017
00018
00019 #define CON_TYPE 0x02
00020
00021
00022 #define CON_LOCK 0x04
00023
00024
00025 #define CON_COMPLETE 0x08
00026
00027
00028 #define CON_TOKEN 0x10
00029
00030
00031 #define CON_DBREF 0x20
00032
00033
00034
00035 static MSTATE md;
00036
00037 static void promote_match(dbref what, int confidence)
00038 {
00039
00040
00041
00042
00043 if(md.pref_type != NOTYPE) {
00044 if(Good_obj(what) && (Typeof(what) == md.pref_type))
00045 confidence |= CON_TYPE;
00046 }
00047 if(md.check_keys) {
00048 MSTATE save_md;
00049
00050 save_match_state(&save_md);
00051 if(Good_obj(what) && could_doit(md.player, what, A_LOCK));
00052 confidence |= CON_LOCK;
00053 restore_match_state(&save_md);
00054 }
00055
00056
00057
00058
00059 if(md.count == 0) {
00060 md.match = what;
00061 md.confidence = confidence;
00062 md.count = 1;
00063 return;
00064 }
00065
00066
00067
00068
00069 if(confidence < md.confidence) {
00070 return;
00071 }
00072
00073
00074
00075
00076 if(confidence > md.confidence) {
00077 md.match = what;
00078 md.confidence = confidence;
00079 md.count = 1;
00080 return;
00081 }
00082
00083
00084
00085
00086 if(random() % 2) {
00087 md.match = what;
00088 }
00089 md.count++;
00090 return;
00091 }
00092
00093
00094
00095
00096
00097
00098
00099 static char *munge_space_for_match(char *name)
00100 {
00101 static char buffer[LBUF_SIZE];
00102 char *p, *q;
00103
00104 p = name;
00105 q = buffer;
00106 while (isspace(*p))
00107 p++;
00108
00109
00110 while (*p) {
00111 while (*p && !isspace(*p))
00112 *q++ = *p++;
00113 while (*p && isspace(*++p));
00114 if(*p)
00115 *q++ = ' ';
00116 }
00117 *q = '\0';
00118
00119
00120
00121
00122 return (buffer);
00123 }
00124
00125 void match_player(void)
00126 {
00127 dbref match;
00128 char *p;
00129
00130 if(md.confidence >= CON_DBREF) {
00131 return;
00132 }
00133 if(Good_obj(md.absolute_form) && isPlayer(md.absolute_form)) {
00134 promote_match(md.absolute_form, CON_DBREF);
00135 return;
00136 }
00137 if(*md.string == LOOKUP_TOKEN) {
00138 for(p = md.string + 1; isspace(*p); p++);
00139 match = lookup_player(NOTHING, p, 1);
00140 if(Good_obj(match)) {
00141 promote_match(match, CON_TOKEN);
00142 }
00143 }
00144 }
00145
00146
00147
00148
00149
00150 static dbref absolute_name(int need_pound)
00151 {
00152 dbref match;
00153 char *mname;
00154
00155 mname = md.string;
00156 if(need_pound) {
00157 if(*md.string != NUMBER_TOKEN) {
00158 return NOTHING;
00159 } else {
00160 mname++;
00161 }
00162 }
00163 match = parse_dbref(mname);
00164 if(Good_obj(match)) {
00165 return match;
00166 }
00167 return NOTHING;
00168 }
00169
00170 void match_absolute(void)
00171 {
00172 if(md.confidence >= CON_DBREF)
00173 return;
00174 if(Good_obj(md.absolute_form))
00175 promote_match(md.absolute_form, CON_DBREF);
00176 }
00177
00178 void match_numeric(void)
00179 {
00180 dbref match;
00181
00182 if(md.confidence >= CON_DBREF)
00183 return;
00184 match = absolute_name(0);
00185 if(Good_obj(match))
00186 promote_match(match, CON_DBREF);
00187 }
00188
00189 void match_me(void)
00190 {
00191 if(md.confidence >= CON_DBREF)
00192 return;
00193 if(Good_obj(md.absolute_form) && (md.absolute_form == md.player)) {
00194 promote_match(md.player, CON_DBREF | CON_LOCAL);
00195 return;
00196 }
00197 if(!string_compare(md.string, "me"))
00198 promote_match(md.player, CON_TOKEN | CON_LOCAL);
00199 return;
00200 }
00201
00202 void match_home(void)
00203 {
00204 if(md.confidence >= CON_DBREF)
00205 return;
00206 if(!string_compare(md.string, "home"))
00207 promote_match(HOME, CON_TOKEN);
00208 return;
00209 }
00210
00211 void match_here(void)
00212 {
00213 dbref loc;
00214
00215 if(md.confidence >= CON_DBREF)
00216 return;
00217 if(Good_obj(md.player) && Has_location(md.player)) {
00218 loc = Location(md.player);
00219 if(Good_obj(loc)) {
00220 if(loc == md.absolute_form) {
00221 promote_match(loc, CON_DBREF | CON_LOCAL);
00222 } else if(!string_compare(md.string, "here")) {
00223 promote_match(loc, CON_TOKEN | CON_LOCAL);
00224 } else if(!string_compare(md.string, (char *) PureName(loc))) {
00225 promote_match(loc, CON_COMPLETE | CON_LOCAL);
00226 }
00227 }
00228 }
00229 }
00230
00231 static void match_list(dbref first, int local)
00232 {
00233 char *namebuf;
00234
00235 if(md.confidence >= CON_DBREF)
00236 return;
00237 DOLIST(first, first) {
00238 if(first == md.absolute_form) {
00239 promote_match(first, CON_DBREF | local);
00240 return;
00241 }
00242
00243
00244
00245
00246
00247
00248 namebuf = (char *) PureName(first);
00249
00250 if(!string_compare(namebuf, md.string)) {
00251 promote_match(first, CON_COMPLETE | local);
00252 } else if(string_match(namebuf, md.string)) {
00253 promote_match(first, local);
00254 }
00255 }
00256 }
00257
00258 void match_possession(void)
00259 {
00260 if(md.confidence >= CON_DBREF)
00261 return;
00262 if(Good_obj(md.player) && Has_contents(md.player))
00263 match_list(Contents(md.player), CON_LOCAL);
00264 }
00265
00266 void match_neighbor(void)
00267 {
00268 dbref loc;
00269
00270 if(md.confidence >= CON_DBREF)
00271 return;
00272 if(Good_obj(md.player) && Has_location(md.player)) {
00273 loc = Location(md.player);
00274 if(Good_obj(loc)) {
00275 match_list(Contents(loc), CON_LOCAL);
00276 }
00277 }
00278 }
00279
00280 static int match_exit_internal(dbref loc, dbref baseloc, int local)
00281 {
00282 dbref exit;
00283 int result, key;
00284
00285 if(!Good_obj(loc) || !Has_exits(loc))
00286 return 1;
00287
00288 result = 0;
00289 DOLIST(exit, Exits(loc)) {
00290 if(exit == md.absolute_form) {
00291 key = 0;
00292 if(Examinable(md.player, loc))
00293 key |= VE_LOC_XAM;
00294 if(Dark(loc))
00295 key |= VE_LOC_DARK;
00296 if(Dark(baseloc))
00297 key |= VE_BASE_DARK;
00298 if(exit_visible(exit, md.player, key)) {
00299 promote_match(exit, CON_DBREF | local);
00300 return 1;
00301 }
00302 }
00303 if(matches_exit_from_list(md.string, (char *) PureName(exit))) {
00304 promote_match(exit, CON_COMPLETE | local);
00305 result = 1;
00306 }
00307 }
00308 return result;
00309 }
00310
00311 void match_exit(void)
00312 {
00313 dbref loc;
00314
00315 if(md.confidence >= CON_DBREF)
00316 return;
00317 loc = Location(md.player);
00318 if(Good_obj(md.player) && Has_location(md.player))
00319 (void) match_exit_internal(loc, loc, CON_LOCAL);
00320 }
00321
00322 void match_exit_with_parents(void)
00323 {
00324 dbref loc, parent;
00325 int lev;
00326
00327 if(md.confidence >= CON_DBREF)
00328 return;
00329 if(Good_obj(md.player) && Has_location(md.player)) {
00330 loc = Location(md.player);
00331 ITER_PARENTS(loc, parent, lev) {
00332 if(match_exit_internal(parent, loc, CON_LOCAL))
00333 break;
00334 }
00335 }
00336 }
00337
00338 void match_carried_exit(void)
00339 {
00340 if(md.confidence >= CON_DBREF)
00341 return;
00342 if(Good_obj(md.player) && Has_exits(md.player))
00343 (void) match_exit_internal(md.player, md.player, CON_LOCAL);
00344 }
00345
00346 void match_carried_exit_with_parents(void)
00347 {
00348 dbref parent;
00349 int lev;
00350
00351 if(md.confidence >= CON_DBREF)
00352 return;
00353 if(Good_obj(md.player) && (Has_exits(md.player) || isRoom(md.player))) {
00354 ITER_PARENTS(md.player, parent, lev) {
00355 if(match_exit_internal(parent, md.player, CON_LOCAL))
00356 break;
00357 }
00358 }
00359 }
00360
00361 void match_master_exit(void)
00362 {
00363 if(md.confidence >= CON_DBREF)
00364 return;
00365 if(Good_obj(md.player) && Has_exits(md.player))
00366 (void) match_exit_internal(mudconf.master_room,
00367 mudconf.master_room, 0);
00368 }
00369
00370 void match_zone_exit(void)
00371 {
00372 if(md.confidence >= CON_DBREF)
00373 return;
00374 if(Good_obj(md.player) && Has_exits(md.player))
00375 (void) match_exit_internal(Zone(md.player), Zone(md.player), 0);
00376 }
00377
00378 void match_everything(int key)
00379 {
00380
00381
00382
00383
00384
00385
00386 match_me();
00387 match_here();
00388 match_absolute();
00389 if(key & MAT_NUMERIC)
00390 match_numeric();
00391 if(key & MAT_HOME)
00392 match_home();
00393 match_player();
00394 if(md.confidence >= CON_TOKEN)
00395 return;
00396
00397 if(!(key & MAT_NO_EXITS)) {
00398 if(key & MAT_EXIT_PARENTS) {
00399 match_carried_exit_with_parents();
00400 match_exit_with_parents();
00401 } else {
00402 match_carried_exit();
00403 match_exit();
00404 }
00405 }
00406 match_neighbor();
00407 match_possession();
00408 }
00409
00410 dbref match_result(void)
00411 {
00412 switch (md.count) {
00413 case 0:
00414 return NOTHING;
00415 case 1:
00416 return md.match;
00417 default:
00418 return AMBIGUOUS;
00419 }
00420 }
00421
00422
00423
00424
00425
00426 dbref last_match_result(void)
00427 {
00428 return md.match;
00429 }
00430
00431 dbref match_status(player, match)
00432 dbref player, match;
00433 {
00434 switch (match) {
00435 case NOTHING:
00436 notify(player, NOMATCH_MESSAGE);
00437 return NOTHING;
00438 case AMBIGUOUS:
00439 notify(player, AMBIGUOUS_MESSAGE);
00440 return NOTHING;
00441 case NOPERM:
00442 notify(player, NOPERM_MESSAGE);
00443 return NOTHING;
00444 }
00445 if(Good_obj(match) && Dark(match) && Good_obj(player) &&
00446 !WizRoy(Owner(player)) && !Builder(Owner(player)))
00447 return match_status(player, NOTHING);
00448 return match;
00449 }
00450
00451 dbref noisy_match_result(void)
00452 {
00453 return match_status(md.player, match_result());
00454 }
00455
00456 dbref dispatched_match_result(player)
00457 dbref player;
00458 {
00459 return match_status(player, match_result());
00460 }
00461
00462 int matched_locally(void)
00463 {
00464 return (md.confidence & CON_LOCAL);
00465 }
00466
00467 void save_match_state(mstate)
00468 MSTATE *mstate;
00469 {
00470 mstate->confidence = md.confidence;
00471 mstate->count = md.count;
00472 mstate->pref_type = md.pref_type;
00473 mstate->check_keys = md.check_keys;
00474 mstate->absolute_form = md.absolute_form;
00475 mstate->match = md.match;
00476 mstate->player = md.player;
00477 mstate->string = alloc_lbuf("save_match_state");
00478 StringCopy(mstate->string, md.string);
00479 }
00480
00481 void restore_match_state(mstate)
00482 MSTATE *mstate;
00483 {
00484 md.confidence = mstate->confidence;
00485 md.count = mstate->count;
00486 md.pref_type = mstate->pref_type;
00487 md.check_keys = mstate->check_keys;
00488 md.absolute_form = mstate->absolute_form;
00489 md.match = mstate->match;
00490 md.player = mstate->player;
00491 StringCopy(md.string, mstate->string);
00492 free_lbuf(mstate->string);
00493 }
00494
00495 void init_match(dbref player, char *name, int type)
00496 {
00497 md.confidence = -1;
00498 md.count = md.check_keys = 0;
00499 md.pref_type = type;
00500 md.match = NOTHING;
00501 md.player = player;
00502 md.string = munge_space_for_match((char *) name);
00503 md.absolute_form = absolute_name(1);
00504 }
00505
00506 void init_match_check_keys(dbref player, char *name, int type)
00507 {
00508 init_match(player, name, type);
00509 md.check_keys = 1;
00510 }