/**************************************************************************** * ^ +----- | / ^ ^ | | +-\ * * / \ | | / |\ /| | | | \ * * / \ +--- |< | \ / | | | | | * * /-----\ | | \ | v | | | | / * * / \ | | \ | | +-----+ +-/ * **************************************************************************** * AFKMud Copyright 1997-2003 by Roger Libiez (Samson), * * Levi Beckerson (Whir), Michael Ward (Tarl), Erik Wolfe (Dwip), * * Cameron Carroll (Cam), Cyberfox, Karangi, Rathian, Raine, and Adjani. * * All Rights Reserved. * * * * Original SMAUG 1.4a written by Thoric (Derek Snider) with Altrag, * * Blodkai, Haus, Narn, Scryn, Swordbearer, Tricops, Gorog, Rennard, * * Grishnakh, Fireblade, and Nivek. * * * * Original MERC 2.1 code by Hatchet, Furey, and Kahn. * * * * Original DikuMUD code by: Hans Staerfeldt, Katja Nyboe, Tom Madsen, * * Michael Seifert, and Sebastian Hammer. * **************************************************************************** * Inter-Port channel sharing module * ****************************************************************************/ /****************************************************** Desolation of the Dragon MUD II (C) 2000-2003 Jesse DeFer http://www.dotd.com dotd@dotd.com ******************************************************/ /*************************************************************************** * _/ _/ * * _/_/_/ _/_/ _/_/_/ _/ _/_/ _/ _/ _/_/_/ * * _/ _/ _/ _/ _/ _/ _/ _/ _/ _/ _/ * * _/ _/ _/ _/ _/ _/ _/ _/ _/ _/ _/ * * _/ _/ _/ _/_/_/ _/ _/_/ _/_/_/ _/_/_/ * *************************************************************************** * Mindcloud Copyright 2001-2003 by Jeff Boschee (Zarius), * * Additional credits are in the help file CODECREDITS * * All Rights Reserved. * ***************************************************************************/ #include <stdio.h> #include <time.h> #include <sys/types.h> #include <sys/ipc.h> #include <sys/msg.h> #include <errno.h> #include <string.h> #include "merc.h" extern int port; //MUD_CHANNEL *find_channel( char *name ); //void send_tochannel( CHAR_DATA *ch, MUD_CHANNEL *channel, char *argument ); //void free_zonedata( CHAR_DATA *ch ); /* License: * 1. This software comes with no warranty. * 2. This software is free, and may not be bought or sold. * 3. This software may be redistributed in source-only form, with this * license intact. * 4. This software may be redistributed with other software, only when * all of the following are met: * 1) the other software is in source form, * 2) the other software is free, * 3) this license does not conflict with the other software's license * 5. The comment below with the author's name must remain intact. */ /* MUD-MUD Communication via SysV IPC Message Queues * Allows multiple muds on the same box to share their immtalk channel * (and possibly other channels) * Author: Jesse DeFer dotd@dotd.com * AKA: Garil, Desolation of the Dragon II MUD - dotd.com 4000 * Version: 1.02 * Date: 9-14-2003 12:30MST * * Ever so slightly nudged and prodded to work in AFKMud by Samson */ /* * Notes: * * Should be very easy to port to any merc derivative, and fairly * * easy to port to anything else. It was written and tested on * * a SMAUG with modified channel code, however it should work on * * any SMAUG without having to modify anything but a few defines. * * Other muds will probably require rewriting recv_text_handler. * * If you re-write recv_text_handler, send it and the defines you * * modified to dotd@dotd.com and I'll include it in the next release. */ /* * Installation: * * 1. Customize this file, including the defines below and * * recv_text_handler (should be obvious what needs customizing) * * 2. Add a snippet like the following to your mud's channel code: * * if ( channel == CHANNEL_IMMTALK ) * * mud_message(ch, channel, argument); * * 3. Add a snippet like the following to your mud's event loop code: * * mud_recv_message(); */ /* customize these defines */ /* this should point to a file, a good file is something that doesn't change * very often, but is owned by you and unique. You should spell the path out * completely, and it NEEDS to be in one place that *ALL* of the ports you want * to use this can reach. So if you have muds in different home directories don't * bother unless you happen to own the whole system. */ #define IPC_KEY_FILE "/home/jeff/muds/mcloud/mudmsgkeyDONTDELETEME" /* the ports the other muds run on, you can include this port too if you want * and the code will skip it automatically, terminate with -1 */ const int other_ports[] = { 4000, 6969, 5000, -1 }; /* end customize these defines */ #define MAX_MSGBUF_LENGTH 2048 key_t keyval; int qid = -2; struct mud_msgbuf { long mtype; char mtext[MAX_MSGBUF_LENGTH + 1]; }; void close_queue(void) { msgctl(qid, IPC_RMID, 0); //bug( "close_queue", 0 ); } int open_queue(void) { struct msqid_ds qstat; int oldqid = qid; qstat.msg_qnum = 0; if (qid == -2) keyval = ftok(IPC_KEY_FILE, 'm'); if (msgctl(qid, IPC_STAT, &qstat) != -1) { if (qstat.msg_qnum > 50) close_queue(); } if ((qid = msgget(keyval, IPC_CREAT | 0666)) == -1) { bug("Unable to msgget keyval", 0); return -1; } if (oldqid != qid) oldqid = qid; return 1; } void mud_send_message(char *arg) { struct mud_msgbuf qbuf; int x; if (open_queue() < 0) return; snprintf(qbuf.mtext, MAX_MSGBUF_LENGTH, "%s", arg); for (x = 0; other_ports[x] != -1; x++) { if (other_ports[x] == port) continue; qbuf.mtype = other_ports[x]; if (msgsnd(qid, &qbuf, strlen(qbuf.mtext) + 1, 0) == -1) bug("mud_send_message", 0); } } void mud_message(CHAR_DATA * ch, char *arg) { char tbuf[MAX_MSGBUF_LENGTH + 1]; //int invis; //bool isinvis = IS_SET( ch->act, PLR_WIZINVIS ); bool isnpc = IS_NPC(ch); //invis = IS_NPC(ch) ? ch->mobinvis : ch->pcdata->wizinvis; snprintf(tbuf, MAX_MSGBUF_LENGTH, "chat 0 2 %d 0 \"%s@mindcloud\" %s", isnpc, ch->name, arg); mud_send_message(tbuf); } void recv_text_handler(char *str) { //MUD_CHANNEL *channel = NULL; CHAR_DATA *ch = NULL; char arg1[MIL], arg2[MIL], arg3[MIL], arg4[MIL], arg5[MIL], chname[MIL]; int ilevel = -1, clevel = -1; bool isnpc, isinvis; str = one_argument(str, arg1); str = one_argument(str, arg2); str = one_argument(str, arg3); str = one_argument(str, arg4); str = one_argument(str, arg5); str = one_argument(str, chname); ilevel = atoi(arg2); clevel = atoi(arg3); isnpc = atoi(arg4); isinvis = atoi(arg5); /* * Massive punt here */ CREATE(ch, CHAR_DATA, 1); if (!isnpc) { CREATE(ch->pcdata, PC_DATA, 1); } else { ch->short_descr = STRALLOC(chname); SET_BIT(ch->act, ACT_IS_NPC); } ch->name = STRALLOC(chname); ch->level = 3; char_to_room(ch, get_room_index(ROOM_VNUM_LIMBO)); talk_channel(ch, str, CHANNEL_CHAT, 0, "chat"); char_from_room(ch); STRFREE(ch->name); STRFREE(ch->short_descr); //free_zonedata( ch ); if (!isnpc) DISPOSE(ch->pcdata); DISPOSE(ch); return; } void mud_recv_message(void) { struct mud_msgbuf qbuf; int ret; if (open_queue() < 0) return; while ((ret = msgrcv(qid, &qbuf, MAX_MSGBUF_LENGTH, port, IPC_NOWAIT)) > 0) recv_text_handler(qbuf.mtext); if (ret == -1 && errno != ENOMSG) bug("mud_recv_message: errno", 0); }