--- deliantra/server/socket/lowlevel.C 2007/01/20 13:47:17 1.32 +++ deliantra/server/socket/lowlevel.C 2007/02/04 21:02:54 1.33 @@ -188,8 +188,8 @@ * Dispatch table for the server. */ static struct packet_type packets[] = { - {"ncom", PC(NewPlayerCmd) PF_PLAYING }, - {"command", PC(PlayerCmd) PF_PLAYING }, + {"ncom", PC(NewPlayerCmd) PF_PLAYING | PF_COMMAND6 }, + {"command", PC(PlayerCmd) PF_PLAYING | PF_COMMAND0 }, {"examine", PC(ExamineCmd) PF_PLAYING }, {"apply", PC(ApplyCmd) PF_PLAYING }, @@ -222,10 +222,38 @@ && (!(pkt->flags & PF_PLAYING) || state == ST_PLAYING); } +// HACK: some commands currently should be executed +// even when the player is frozen. this hack detects +// those commands. it should be folded into may_execute, +// but kept seperate to emphasise the hack aspect, i.e. +// do it better, then remove. +static bool +always_immediate (const client *ns, const packet_type *pkt, const char *data, int len) +{ + if (!(pkt->flags & (PF_COMMAND0 | PF_COMMAND6))) + return false; + + if (!ns->pl || !ns->pl->ob || !ns->pl->ob->map) + return false; + + if (pkt->flags & PF_COMMAND6) + { + data += 6; + len -= 6; + } + + if (len > 4 && !strncmp (data, "say " , 4)) + return true; + if (len > 5 && !strncmp (data, "chat ", 5)) + return true; + + return false; +} + void client::execute (const packet_type *pkt, char *data, int datalen) { - if (may_execute (pkt)) + if (may_execute (pkt) || always_immediate (this, pkt, data, datalen)) { //TODO: only one format if (pkt->flags & PF_PLAYER) @@ -276,7 +304,7 @@ for (packet_type *pkt = packets; pkt < packets + (sizeof (packets) / sizeof (packets[0])); ++pkt) if (!strcmp ((char *)inbuf + 2, pkt->name)) { - if (pkt->flags & PF_PLAYER) + if (pkt->flags & PF_PLAYER && !always_immediate (this, pkt, data, datalen)) queue_command (pkt, data, datalen); else execute (pkt, data, datalen);