From the NannyMUD documentation
2000-12-23
NAME
class4 - A log from TMI, part 4.DESCRIPTION
This is part 4 of some logs from TMI. Rgreene arrives. Profezzorn says: ok, logging is on Profezzorn says: todays topic is Common Problems Profezzorn says: and I will begin by asking you what problems you think are common Profezzorn says: after that I will talk about some problems I have encountered often Guest arrives. Ddane says: syntax errors :) Profezzorn says: of course, 90% of all errors are syntax errors, but that's beside the point Bogglelrer says: bad args to present Profezzorn says: bad arg to present is just an error, it gives very little hint of the real problem Ddane nods solemnly. Profezzorn says: but Profezzorn says: one, very common problem is that people forget that a function used by Baccara says: can't determine users, event after i have setuid Profezzorn says: add_action() can get a zero argument Jeearr says: I have one that might not be so common Jeearr says: but how do you do looping in such a way to prevent eval cost errors> Profezzorn listens to Jearr. Eburger arrives. Profezzorn says: that's a common problem, but the solution(s) aren't exactly intermediate... Jeearr says: for example resetting the eval cost with each loop through Jeearr says: oh ok..i'll talk to youa bout that later then ;) Profezzorn says: bad arg to present is one of the things that can happen when you forget Profezzorn says: that a command can get a zero argument Profezzorn says: two other very common errors of that kind is bad arg to lower_case Profezzorn says: or sscanf Profezzorn says: anybody need an example of this? Baccara nods solemnly. Ddane nods solemnly. Profezzorn says: ok Profezzorn says: let's say we have a shop.. Profezzorn says: with a buy command Profezzorn says: or rather, let's use the sell command for this example... Eburger leaves east. A small gnome appears and cleans some of the boards that are empty. The gnome leaves again. A small gnome appears and cleans some of the boards that are empty. The gnome leaves again. A small gnome appears and cleans some of the boards that are empty. The gnome leaves again. Guest leaves east. Profezzorn says: void init() Profezzorn says: { Profezzorn says: ::init(); Profezzorn says: add_action("sell","sell"); Profezzorn says: } Profezzorn says: int sell(string s) Profezzorn says: { Profezzorn says: object o; Profezzorn says: o=present(s,this_player()); Profezzorn says: /* rest of code */ Profezzorn says: } Profezzorn puts something on the projector. Profezzorn says: now Profezzorn says: let's say that some inquisitive mortal writes just 'sell' Profezzorn says: then the argument will be zero, and not a string at all Profezzorn says: which will result in bad arg 1 to present Profezzorn says: the example is on the project if you need it Profezzorn says: any questions? Ddane says: so, you need to do an error catch, for no argument? Jeearr nods solemnly. Profezzorn says: what you need to write is something like: Jeearr says: or a check of somesort to check what type of thing is being reurned.or is the string Profezzorn says: if(!s) Profezzorn says: { Profezzorn says: notify_fail("Sell what?\n"); Profezzorn says: return 0; Profezzorn says: } Profezzorn says: that should be before the present Baccara raises a hand. Profezzorn says: yes? Baccara says: how about 'can't dertermine user... Baccara says: even i have put seteuid(getuid(this_object())); Profezzorn says: I don't know exactly what your problem is, as I haven't seen the code Profezzorn says: it might be a number of things Profezzorn says: what driver do you use? Baccara says: for example Baccara says: receive_message (string class, string str) { Baccara says: string tmp; Baccara says: if(!rec) return 1; Baccara says: rec_buff = rec_buff + str; Baccara says: if(strlen(rec_buff) > 5000){ Baccara says: write("Transfering data to : "+rec_file+"\n"); Baccara says: write_file("/d/System/data/record/"+rec_file,rec_buff); Baccara says: rec_buff_bak = rec_buff; Baccara says: rec_buff = ""; Baccara says: write("Click.. click.. the recorder makes a noise.\n"); Baccara says: time_stamp(); Baccara says: write("The recorder gets a new blank tape.\n"); Baccara says: so i always got the error msg during write_file Baccara says: im using 0.9.18 Profezzorn says: MUDOS really sucks :) Baccara says: *smile* Profezzorn says: I recommend that you try to write the uid and euid of the object as debug to see that they are really set correctly Pepel arrives. Ddane shakes pepels hand. Pepel shakes ddanes hand. Baccara says: i have put seteuid(getuid(this_object())); Pepel shakes ddanes hand. Profezzorn says: where? Baccara says: in create(){.. Profezzorn says: well, all I can say is that I don't know what the error is Baccara says: ok..thanks Profezzorn says: I can warn of some things that will give problems when you try it though Profezzorn says: like trusting find_call_out Profezzorn says: it says in the manual that find_call_out should return the time left or -1 if no call out is pending Profezzorn says: so it is very easy to just start a call out if none is pending using find_call_out Profezzorn says: not Funnyman arrives. Profezzorn says: find_call_out can return -1 even if a call_out is pending Pepel says: why? Profezzorn says: if, because of lag, that call_out should already have been executed Pepel says: but in that case the callout is gone already? Pepel says: oh , mmhh Profezzorn says: no it might not have been exected, it just should have been Pepel says: does it mean the callout hangs somewhere between the event queue and actual execution, in limbo? India leaves east. Profezzorn says: no, the even queue says that it should happen at the time T Profezzorn says: but during that exact second the mud is doing something else A small gnome appears and cleans some of the boards that are empty. The gnome leaves again. Profezzorn says: so when find_call_out finds the call out it is the time T+1 Profezzorn says: and it still haven't been executed Funnyman says: I call this a bug in the gamedriver. Profezzorn says: yes it is Pepel nods solemnly. Funnyman says: is it that clever to discuss bugs here instead of telling the driver writes to fix it? Funnyman says: s/writes/writers Profezzorn says: maybe not Profezzorn says: but the bug is around at ever mud in the world Profezzorn says: kind of too late to fix it everywhere Funnyman says: that's your opinion ;-) Profezzorn says: you are welcome to inform the dirverhackers about this problem of course Profezzorn says: but until then, beware ok? Profezzorn says: I have accidentially stopped a mud because of this bug Profezzorn says: shall we move on to a common problem that is _not_ a bug Funnyman nods solemnly. Baccara nods solemnly. Profezzorn says: well, one common bug is to do add actions to functions that are lfuns Profezzorn says: most commonly drop() or exit() Profezzorn says: especially add_action("exit","exit") is not good on a compat driver Pepel shivers from the cold. Profezzorn says: as exit is called when a living leaves that room Mbeltt says: What should you do instead? Profezzorn says: add_action("exit_cmd","exit") for instance Funnyman says: uhm, what else do I give as argument to add_action() instead of an lfun? Besides, isn't drop and exit mudlib depended? (And exit() is/was a compat mode special thingy) Profezzorn says: depends on how you define an lfun Profezzorn says: what I'm warning about is add action to functons with predefined meanings Profezzorn says: drop is very mudilb depended, but very common Profezzorn says: exit() is compat only, but _extremly_ nasty when you do a thing like that Profezzorn says: any questions? Baccara says: how about the common th catch real email-adr ? :) Profezzorn says: the common what? Baccara says: to catch real user@hostname from the users Pepel says: how? Profezzorn says: that's hardly intermediate Profezzorn says: the idea is to connect to the identdaemon on the users computer and ask who's owning that socket. Pepel grins evilly. Mbeltt grins evilly. Profezzorn says: let's talk some more 'normal' problems instead Baccara says: ok Pepel nods solemnly. Ddane says: how hard would it be, to do a 'step-through' to another mud? Ddane says: i.e. i want a mud, with 'doors' to other muds, within it? Profezzorn says: depends on what kind of demands you have on your doors Profezzorn says: in any case it's hardly recommendable Pepel says: thats certainly a kind of `intermediate' problem - though in some special way of intermediate :-) Profezzorn says: as it is much faster to telnet directly to the mud you want Ddane nods solemnly. Pepel says: but much more boring :-) Profezzorn says: it is in no way intermediate asit require usage of socket code Ddane says: actually, i was wanting a door through which a player had to go 'fetch' a quest-obj, from another mud... Pepel says: i guess the socket suff is easiest part of it ... Ddane says: the player, on 'returning' would have/not have this object in possesion Profezzorn says: object transfer between muds is even harder Ddane says: well, couldn't you have the code for the object, on both muds, and return a value through the 'door' ? Profezzorn says: anything is possible Profezzorn says: literally Ddane smiles happily. A small gnome appears and cleans some of the boards that are empty. The gnome leaves again. A small gnome appears and cleans some of the boards that are empty. The gnome leaves again. Pepel says: nod - goes not gives it not Ddane says: pepel, i would like to talk to you about this, on NF, sometime, okay? Profezzorn says: but if you call that a Baccara says: maybe you can check it from euid and compare it with all your wiz, if false than destruct Profezzorn says: "common" problem, then I dunno Pepel nods solemnly. Profezzorn says: a better example of common problems is things like lost error messages because enable_commands() changes this player Pepel says: ? Profezzorn says: when coding a monster, you normally do enable_commands() somewhere in reset or create Profezzorn says: that changes this_player() to this_object() Pepel nods solemnly. Funnyman says: only if this_object() exists ... Profezzorn says: if an error occurs after that, no error message will be written to the cloner, as he/she/it is not this_player() anymore Profezzorn says: if this_object() doesn't exist, why do enable_commands() silly Mbeltt says: How do you prevent that? Profezzorn says: prevent what? Mbeltt says: Losing the error message. Profezzorn says: you don't Profezzorn says: just remember to read the log Profezzorn says: /lpmud.log on most muds Mbeltt says: Oh. Profezzorn says: but /.debug.log is better Pepel says: mmhh, dish wahsers are device to wahs tedious dishes - log readers ... ? Profezzorn says: well, if you want a nice solution, make a clone commands that checks if Profezzorn says: that log grows and write the last part of it if it does Profezzorn says: my wiztool, the shell, does that Ddane says: here's one i have a problem with... Profezzorn listens to Ddane. Ddane says: i have an item, that changes my long/short descrips. to any other object, Ddane says: but, it still includes my inventory Ddane says: nothing i have tried so far, has been able to override this effect... Ddane says: any solutions? Profezzorn says: there are solutions Profezzorn says: no nice solutions though :) Profezzorn says: it can be fixed with a shadow and chaning can_put_and_get on you Profezzorn says: or shadowing all the objects in your inv and removing their short() Profezzorn says: there are other, even more ugly solutions Ddane says: the problem i have, with some of the wiz-tools, is the short() is protected, so i can't change it Ddane says: and, i would like to keep those in my possesion, if at all possible Profezzorn says: my question is: why change yourself? why not use a completely new object that relays everything to you? Pepel grins evilly. Ddane says: i am/was imitating an npc, or an object, to 'snoop' on quest solvers... Profezzorn says: so why not imitate it with another object and let it relay eveyrhing it hears to you? Ddane says: i have used this to allow myslef to be treated as a 'familiar' at times Ddane shrugs helplessly. Profezzorn says: it's not the same thing maybe, but it is much more flexible Ddane nods solemnly. Profezzorn says: an input_to can relay everything you write at commands to that object Ddane says: i suppose i would try that angle, next time... Profezzorn says: any other questions, before I close class? Ddane says: just one... Funnyman says: input_to() and command()? Funnyman says: are you serious about this? Ddane nods solemnly. Ddane says: is input_to an lfun? Profezzorn says: for controlling an npc, yes funnyman Profezzorn says: no, input_to is an efun Funnyman says: then how do you get around static lfuns? Profezzorn says: read the documentation on your local mud, I'm sure you'll find it interesting Profezzorn says: well, you don't of course Pepel grins evilly. Profezzorn says: but the whole point is to make something that you can use a cover, so you don't give it wiztools and such Funnyman says: that's the point. It still is no 100% proof solution. Profezzorn says: you just write ! when you want to do something 'normal' Profezzorn says: no, it is not a 100% proof solution Profezzorn says: but I can tell you straight off, that no matter the problem there is never one that is optimal in all cases Funnyman says: I think this depends on the mudlib. Profezzorn says: not really Funnyman says: if your lib allows to add hooks for such things, then it is no problem at all. Profezzorn says: unless TMI mudlib does very strange things Baccara smiles happily. Baccara says: im using mudlib also :) i like it Ddane says: i have to leave now Profezzorn says: yes, but if you have such a lib, it's not a problem in the first case, is it? Ddane shakes profezzorns hand. Profezzorn says: yes, class is over now anyway Ddane says: thanks Ddane shakes pepels hand. Pepel shakes ddanes hand. Ddane says: cya'll next time :) Ddane just left the school. Baccara waves good-bye. Profezzorn says: ok Mbeltt thanks profezzorn. Profezzorn waves good-bye. Mbeltt just left the school.