/****************************************************************************
* ^ +----- | / ^ ^ | | +-\ *
* / \ | | / |\ /| | | | \ *
* / \ +--- |< | \ / | | | | | *
* /-----\ | | \ | 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);
}