322 lines
5.4 KiB
C++
322 lines
5.4 KiB
C++
|
#include <string.h>
|
|||
|
#include <dos.h>
|
|||
|
#include <time.h>
|
|||
|
#include <ctype.h>
|
|||
|
#include "desqview.hpp"
|
|||
|
#include "proboard.hpp"
|
|||
|
|
|||
|
const MAX_LOCK_TRIES = 500;
|
|||
|
const LOCK_PAUSE = 10;
|
|||
|
|
|||
|
static char *lock_err_msg = "CHAT FILE LOCKING ERROR (%d)";
|
|||
|
|
|||
|
class chatdata
|
|||
|
{
|
|||
|
int online;
|
|||
|
int head,tail;
|
|||
|
char data[240];
|
|||
|
static File f[2];
|
|||
|
static int node[2];
|
|||
|
public:
|
|||
|
chatdata(int n1,int n2);
|
|||
|
~chatdata();
|
|||
|
void queue(char x);
|
|||
|
int getnext(char *);
|
|||
|
};
|
|||
|
|
|||
|
File chatdata::f[2];
|
|||
|
|
|||
|
int chatdata::node[2];
|
|||
|
|
|||
|
chatdata::chatdata(int n1,int n2)
|
|||
|
{
|
|||
|
node[0] = n1;
|
|||
|
node[1] = n2;
|
|||
|
|
|||
|
if(!f[0].open(form("%sCHAT%d.DAT",syspath,node[0]),fmode_rw | fmode_shared | fmode_copen))
|
|||
|
return;
|
|||
|
|
|||
|
memset(this,0,sizeof(*this));
|
|||
|
|
|||
|
f[0].write(this,sizeof(*this));
|
|||
|
|
|||
|
time_t t = time(NULL);
|
|||
|
|
|||
|
for(;;)
|
|||
|
{
|
|||
|
if(f[1].open(form("%sCHAT%d.DAT",syspath,node[1]),fmode_rw | fmode_shared)) break;
|
|||
|
|
|||
|
if((time(NULL)-t)>20)
|
|||
|
{
|
|||
|
LOG("File sharing error during chat!");
|
|||
|
break;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
chatdata::~chatdata()
|
|||
|
{
|
|||
|
f[0].close();
|
|||
|
f[1].close();
|
|||
|
}
|
|||
|
|
|||
|
void
|
|||
|
chatdata::queue(char c)
|
|||
|
{
|
|||
|
for(int i=0;i<MAX_LOCK_TRIES;i++)
|
|||
|
{
|
|||
|
if(f[0].lock(0,sizeof(*this))) break;
|
|||
|
msleep(LOCK_PAUSE);
|
|||
|
}
|
|||
|
|
|||
|
if(i==MAX_LOCK_TRIES)
|
|||
|
LOG(lock_err_msg,f[0].error());
|
|||
|
|
|||
|
f[0].seek(0);
|
|||
|
f[0].read(this,sizeof(*this));
|
|||
|
|
|||
|
data[tail++]=c;
|
|||
|
|
|||
|
if(tail==240)
|
|||
|
tail=0;
|
|||
|
|
|||
|
f[0].seek(0);
|
|||
|
f[0].write(this,sizeof(*this));
|
|||
|
|
|||
|
f[0].unlock(0,sizeof(*this));
|
|||
|
}
|
|||
|
|
|||
|
int
|
|||
|
chatdata::getnext(char *buffer)
|
|||
|
{
|
|||
|
for(int i=0;i<MAX_LOCK_TRIES;i++)
|
|||
|
{
|
|||
|
if(f[1].lock(0,sizeof(*this))) break;
|
|||
|
msleep(LOCK_PAUSE);
|
|||
|
}
|
|||
|
|
|||
|
if(i==MAX_LOCK_TRIES)
|
|||
|
LOG(lock_err_msg,f[1].error());
|
|||
|
|
|||
|
f[1].seek(0);
|
|||
|
f[1].read(this,sizeof(*this));
|
|||
|
|
|||
|
for(i=0;i<240;i++)
|
|||
|
{
|
|||
|
if(head==tail)
|
|||
|
break;
|
|||
|
|
|||
|
buffer[i] = data[head++];
|
|||
|
|
|||
|
if(head==240)
|
|||
|
head=0;
|
|||
|
}
|
|||
|
|
|||
|
f[1].seek(0);
|
|||
|
f[1].write(this,sizeof(*this));
|
|||
|
f[1].unlock(0,sizeof(*this));
|
|||
|
|
|||
|
return i;
|
|||
|
}
|
|||
|
|
|||
|
void
|
|||
|
multichat(char *data)
|
|||
|
{
|
|||
|
int node2;
|
|||
|
|
|||
|
io << "\n\n\f" << S_MCHAT_TITLE << "\n\n";
|
|||
|
|
|||
|
show_users_online(String("/MC ") + data);
|
|||
|
|
|||
|
io << "\n\n" << S_MCHAT_ENTER_NODE_NUMBER;
|
|||
|
|
|||
|
if(io.read(node2,3)<0)
|
|||
|
return;
|
|||
|
|
|||
|
io << "\n\n" << S_MCHAT_CALLING_OTHER_NODE << '\xFF';
|
|||
|
|
|||
|
if(node2==node_number || node2>cfg.numnodes || node2<=0)
|
|||
|
return;
|
|||
|
|
|||
|
user_online uo;
|
|||
|
uo.setstatus(UO_BROWSING);
|
|||
|
|
|||
|
switch(uo.chatreq(node2))
|
|||
|
{
|
|||
|
case 1:
|
|||
|
uo.setstatus(UO_BUSY,node2);
|
|||
|
|
|||
|
case 2:
|
|||
|
io << S_MCHAT_NODE_IS_NOT_AVAILABLE << "\n\n" << S_PRESS_ENTER_TO_CONTINUE;
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
io << S_MCHAT_STARTED << "\n\n\xFF";
|
|||
|
|
|||
|
multilinechat(node2);
|
|||
|
|
|||
|
uo.setstatus(UO_BROWSING);
|
|||
|
|
|||
|
io << "\n\n" << S_MULTILINE_CHAT_ENDED << ' ' << S_PRESS_ENTER_TO_CONTINUE;
|
|||
|
}
|
|||
|
|
|||
|
void
|
|||
|
multilinechat(int n)
|
|||
|
{
|
|||
|
int node1,node2;
|
|||
|
char buffer[240];
|
|||
|
user_online uo;
|
|||
|
int last=0;
|
|||
|
String s;
|
|||
|
|
|||
|
node1 = node_number;
|
|||
|
node2 = n;
|
|||
|
|
|||
|
LOG(1,"Multiline chat started");
|
|||
|
|
|||
|
chatdata cd(node1,node2);
|
|||
|
|
|||
|
uo.setstatus(UO_CHATTING);
|
|||
|
|
|||
|
for(int i=0;;i++)
|
|||
|
{
|
|||
|
char x;
|
|||
|
|
|||
|
if((x=io.readkey())!=0)
|
|||
|
{
|
|||
|
if(x<8)
|
|||
|
continue;
|
|||
|
|
|||
|
if(x==27)
|
|||
|
break;
|
|||
|
|
|||
|
if(last!=1)
|
|||
|
{
|
|||
|
if(avatar)
|
|||
|
io << "\x16\x01\x0B\xFF";
|
|||
|
else
|
|||
|
if(ansi_mode)
|
|||
|
io << "[1;36m\xFF";
|
|||
|
}
|
|||
|
|
|||
|
last=1;
|
|||
|
|
|||
|
if(x=='\t') x=' ';
|
|||
|
|
|||
|
if(x!=8) io << x << char(0xFF);
|
|||
|
|
|||
|
switch(x)
|
|||
|
{
|
|||
|
case 8:
|
|||
|
if(s.len()>0)
|
|||
|
{
|
|||
|
s[s.len()-1]=0;
|
|||
|
io << "\b \b\xFF";
|
|||
|
}
|
|||
|
break;
|
|||
|
|
|||
|
case 13:
|
|||
|
io << '\n' << char(255);
|
|||
|
s="";
|
|||
|
break;
|
|||
|
|
|||
|
default:
|
|||
|
s << (char)x;
|
|||
|
}
|
|||
|
|
|||
|
if(s.len()>78)
|
|||
|
{
|
|||
|
String wrap;
|
|||
|
|
|||
|
int l = wordwrap(s,wrap,78);
|
|||
|
|
|||
|
for(int i=0;i<l;i++)
|
|||
|
io << "\b \b\xFF";
|
|||
|
|
|||
|
s = wrap;
|
|||
|
|
|||
|
io << '\n' << s << char(0xFF);
|
|||
|
}
|
|||
|
|
|||
|
cd.queue(x);
|
|||
|
DV_timeslice();
|
|||
|
msleep(10);
|
|||
|
continue;
|
|||
|
}
|
|||
|
|
|||
|
DV_timeslice();
|
|||
|
msleep(100);
|
|||
|
|
|||
|
if(i>5)
|
|||
|
{
|
|||
|
i = uo.getstatus(node2);
|
|||
|
|
|||
|
if(i==UO_OFFLINE)
|
|||
|
{
|
|||
|
io << "\n\n" << S_MCHAT_OTHER_NODE_HUNG_UP << '\xFF';
|
|||
|
return;
|
|||
|
}
|
|||
|
i=0;
|
|||
|
}
|
|||
|
|
|||
|
int count = cd.getnext(buffer);
|
|||
|
|
|||
|
for(int i=0;i<count;i++)
|
|||
|
{
|
|||
|
char x=buffer[i];
|
|||
|
|
|||
|
if(last!=2)
|
|||
|
{
|
|||
|
if(avatar)
|
|||
|
io << "\x16\x01\x07\xFF";
|
|||
|
else
|
|||
|
if(ansi_mode)
|
|||
|
io << "[0;37m\xFF";
|
|||
|
}
|
|||
|
|
|||
|
last=2;
|
|||
|
|
|||
|
if(x==1) return;
|
|||
|
|
|||
|
if(x=='\t') x=' ';
|
|||
|
|
|||
|
if(x!=8)
|
|||
|
io << x << char(0xFF);
|
|||
|
|
|||
|
switch(x)
|
|||
|
{
|
|||
|
case 8:
|
|||
|
if(s.len()>0)
|
|||
|
{
|
|||
|
s[s.len()-1]=0;
|
|||
|
io << "\b \b\xFF";
|
|||
|
}
|
|||
|
break;
|
|||
|
|
|||
|
case 13:
|
|||
|
io << "\n\xFF";
|
|||
|
s = "";
|
|||
|
break;
|
|||
|
|
|||
|
default:
|
|||
|
s << (char)x;
|
|||
|
}
|
|||
|
|
|||
|
if(s.len()>78)
|
|||
|
{
|
|||
|
String wrap;
|
|||
|
int l=wordwrap(s,wrap,78);
|
|||
|
for(int i=0;i<l;i++) io << "\b \b\xFF";
|
|||
|
s=wrap;
|
|||
|
io << '\n' << s << char(0xFF);
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
cd.queue(1);
|
|||
|
|
|||
|
LOG(1,"Multiline chat ended");
|
|||
|
}
|
|||
|
|