Skip to content
Snippets Groups Projects
Commit 7f3a536a authored by mcmlxxix's avatar mcmlxxix
Browse files

Cleaned up old code, now uses Graphic()

object windowed chat. str_cmds accessible from
full screen mode, fixed scrollbar
parent 6e0fe966
Branches
Tags
No related merge requests found
......@@ -38,200 +38,194 @@ function Chat(key,engine)
{
while(1)
{
if(engine.stream)
{
var packet=engine.stream.receive();
if(packet<0) exit();
else if(!packet==0 && (packet.room==engine.room || packet.scope==global_scope))
engine.receive();
key=console.inkey(K_NOCRLF|K_NOSPIN|K_NOECHO,5);
if(key) {
engine.processKey(key);
switch(key.toUpperCase())
{
engine.processData(packet.data);
case '\x1b':
engine.exit();
return false;
default:
key="";
break;
}
}
key=console.inkey(K_NOCRLF|K_NOSPIN|K_NOECHO,5);
if(key) engine.processKey(key);
switch(key.toUpperCase())
{
case '\x1b':
return false;
default:
key="";
break;
}
}
}
}
//*************MAIN ENGINE*************
load("commclient.js");
load("scrollbar.js");
load("graphic.js");
load("str_cmds.js");
load("nodedefs.js");
bbs.sys_status |= SS_PAUSEOFF;
oldpass=console.ctrl_key_passthru;
function ChatEngine(root,stream)
function ChatEngine(root)
{
const local_color= "\1n\1g";
const remote_color= "\1n\1c";
const alert_color= "\1n\1r\1h";
const notice_color= "\1n\1k\1h";
const input_color= "\1n\1y";
const private_color= "\1n\1y";
const global_color= "\1n\1m";
const flag_normal= "#";
const flag_global= "!";
const flag_private= "%";
const flag_alert= 2;
const flag_notice= 1;
const flag_message= 0;
var root_dir= (root?root:system.exec_dir);
var scope= normal_scope;
var messages= [];
this.stream= stream?stream:new ServiceConnection("chat");
this.buffer= "";
this.room;
this.fullscreen;
this.columns;
this.rows;
this.x;
this.y;
this.boxed;
this.lined;
this.input_line;
this.scrollbar;
const local_color= "\1n\1g";
const remote_color= "\1n\1c";
const alert_color= "\1r\1h";
const notice_color= "\1n\1y";
const input_color= "\1n";
const private_color= "\1y\1h";
const global_color= "\1n\1m";
//TODO: the only time this will be used is for storing chat history
//maybe give ALL chat history files their own home, independent of the parent script
var root_dir=(root?root:js.exec_dir);
var stream=new ServiceConnection("chat");
var scope=flag_normal;
var window=false;
var message=new Object();
var fullscreen=true;
var scrollbar=false;
var background="\0010";
var ignore=[];
this.buffer="";
this.room="main";
this.columns=console.screen_columns;
this.rows=console.screen_rows;
this.x=1;
this.y=1;
this.input_line;
// USEFUL METHODS
this.init=function(room,input_line,columns,rows,posx,posy,lined,boxed,userlist) //NOTE: DESTROYS BUFFER AND MESSAGE LIST
this.init=function(room,c,r,x,y,bg,ix,iy,iw) //NOTE: DESTROYS BUFFER AND MESSAGE LIST
{
//DEFAULT SETTINGS
this.columns=columns?columns: 79; //chat window width
this.rows=rows?rows: 24; //chat window height
this.x=posx?posx: 1; //top left corner x
this.y=posy?posy: 1; //top left corner y
this.lined=lined?lined: false; //frame chat window? (boolean)
this.boxed=boxed?boxed: false; //frame chat window? (boolean)
this.room=room?room: "default"; //room name (for lobby style interface)
this.userlist=userlist?userlist: false; //separate user list window (boolean)
if(x) this.x=x; //top left corner x
if(y) this.y=y; //top left corner y
if(room) this.room=room; //room name (for lobby style interface)
if(bg) background=bg;
this.buffer="";
messages=[];
if(input_line)
{
this.input_line=new InputLine(this.x,this.y+this.rows+1,this.columns,BG_BLACK);
this.fullscreen=false;
this.scrollbar=new Scrollbar(this.x+this.columns,this.y,this.rows,"vertical","\1k");
}
else this.fullscreen=true;
this.drawLines();
this.drawBox();
this.getNotices();
this.entryMessage();
if(!this.stream)
{
log("unable to connect to service...");
if(c && r) {
fullscreen=false;
this.columns=c;
this.rows=r;
if(this.columns>=console.screen_columns) this.columns=console.screen_columns-1;
scrollbar=new Scrollbar(this.x+this.columns,this.y,this.rows,"vertical","\1k\1h");
}
if(ix && iy) {
this.input_line=new InputLine(ix,iy,iw?iw:this.columns,bg);
fullscreen=false;
} else if(ix || iy) {
log("invalid input line parameters",LOG_WARNING);
return false;
}
if(!fullscreen) {
console.ctrlkey_passthru="+ACGKLOPQRTUVWXYZ_";
bbs.sys_status|=SS_MOFF;
window=new Graphic(this.columns,this.rows,undefined,undefined,true);
}
this.entryMessage();
return true;
}
this.exit=function()
{
this.exitMessage();
stream.close();
console.ctrlkey_passthru=oldpass;
bbs.sys_status&=~SS_MOFF;
bbs.sys_status&=~SS_PAUSEOFF;
console.attributes=ANSI_NORMAL;
}
this.exitMessage=function()
{
if(user.compare_ars("QUIET")) return false;
var message=user.alias + " disconnected";
this.send(message,flag_notice);
}
this.entryMessage=function()
{
var message=user.alias + " has entered the room";
var data=
{
"scope":scope,
"system":system.qwk_id,
"message":message
};
var packet=
{
"scope":scope,
"room":this.room,
"type":"chat",
"data":data
};
this.stream.send(packet);
if(user.compare_ars("QUIET")) return false;
var message=user.alias + " connected";
this.send(message,flag_notice);
}
this.resize=function(x,y,columns,rows) //NOTE: DOES NOT DESTROY BUFFER OR MESSAGE LIST
this.resize=function(x,y,c,r,ix,iy,iw) //NOTE: DOES NOT DESTROY BUFFER OR MESSAGE LIST
{
if(this.lined) clearLine(this.columns+2,this.x-1,this.y-1);
this.clearChatWindow();
if(x) this.x=x;
if(y) this.y=y;
if(columns) this.columns=columns;
if(rows) this.rows=rows;
if(this.input_line)
{
this.input_line.x=this.x;
this.input_line.y=this.y+this.rows+1;
if(c) this.columns=columns;
if(r) this.rows=rows;
if(ix && iy) {
if(!this.input_line) {
this.input_line=new InputLine(ix,iy,iw?iw:this.columns,background);
} else {
this.input_line.x=ix;
this.input_line.y=iy;
this.input_line.width=iw?iw:this.columns;
}
} else {
if(this.input_line) {
this.input_line.x=this.x;
this.input_line.y=this.y+this.rows+1;
this.input_line.width=this.columns;
}
}
if(this.input_line) {
scrollbar=new Scrollbar(this.x+this.columns-1,this.y,this.rows,"vertical",DARKGRAY);
}
this.redraw();
this.scrollbar=new Scrollbar(this.x+this.columns,this.y,this.rows,"vertical",this.scrollbar.color);
}
this.ignoreUser=function(alias)
{
if(ignore[alias]==true) ignore[alias]=false;
else ignore[alias]==true;
}
this.findUser=function(id)
{
//return this.stream.findUser(id);
//return stream.findUser(id);
}
this.clearChatWindow=function() //CLEARS THE ENTIRE CHAT WINDOW
{
clearBlock(this.x,this.y,this.columns,this.rows);
}
this.displayInfo=function(array) //DISPLAYS A TEMPORARY MESSAGE IN THE CHAT WINDOW (NOT STORED)
this.list=function(array,color) //DISPLAYS A TEMPORARY MESSAGE IN THE CHAT WINDOW (NOT STORED)
{
this.clearChatWindow();
var newarray=[];
for(var l=0;l<array.length;l++)
{
var newlines=this.concat(array[l]);
for(var n=0;n<newlines.length;n++)
{
newarray.push(newlines[n]);
}
}
for(item=0;item<newarray.length;item++)
{
console.gotoxy(this.x,this.y+item);
console.putmsg(newarray[item],P_SAVEATR);
}
for(var i=0;i<array.length;i++) this.display(array[i],color);
}
this.notice=function(msg)
{
this.display(notice_color + msg);
this.display(msg,notice_color);
}
this.getNotices=function()
this.alert=function(msg)
{
var msgs=stream.getNotices();
if(!msgs) return false;
stream.notices=[];
for(var m=0;m<msgs.length;m++)
{
this.notice(msgs[m]);
}
}
this.alert=function(msg) //DISPLAYS A MESSAGE ON THE INPUT LINE (OR CURRENT LINE IN FULLSCREEN MODE)
{
if(this.input_line)
{
this.input_line.clear();
console.gotoxy(this.input_line.x,this.input_line.y);
}
console.putmsg(alert_color + msg);
this.display(msg,alert_color);
}
this.redraw=function()
{
this.clearChatWindow();
this.drawLines();
this.drawBox();
this.display();
this.input_line.clear();
this.bufferKey();
this.printBuffer();
}
this.send=function(message)
this.send=function(txt,level,scope,source,target)
{
if(!message.length) return false;
var packet=this.packageData(message);
if(!this.stream.send(packet))
{
this.notice("message could not be sent..");
if(!level) level=flag_message;
if(!scope) scope=flag_normal;
var packet=new Message(txt,level,scope,source,target);
if(!stream.send(packet)) {
this.alert("message not sent.");
}
}
this.receive=function()
{
var packet=stream.receive();
if(packet && packet.message) {
this.processData(packet);
}
scope=normal_scope;
//this.storeHistory(data.message);
}
//INTERNAL METHODS
......@@ -243,7 +237,6 @@ function ChatEngine(root,stream)
case '\x00': /* CTRL-@ (NULL) */
case '\x03': /* CTRL-C (Center Line) */
case '\x04': /* CTRL-D (Quick find in SyncEdit)*/
case '\x09': /* CTRL-I TAB... ToDo expand to spaces */
case '\x0b': /* CTRL-K */
case '\x0c': /* CTRL-L (Insert Line) */
case '\x0e': /* CTRL-N */
......@@ -265,255 +258,283 @@ function ChatEngine(root,stream)
case '\x1b': /* ESC (This should parse extra ANSI sequences) */
case KEY_LEFT:
case KEY_RIGHT:
case '\x02': /* CTRL-B KEY_HOME */
case '\x05': /* CTRL-E KEY_END */
break;
case KEY_UP:
case KEY_DOWN:
case '\x02': /* CTRL-B KEY_HOME */
case '\x05': /* CTRL-E KEY_END */
this.showHistory(key);
break;
case '\b':
this.backSpace();
break;
case '\r':
case '\n':
if(console.strlen(removeSpaces(this.buffer)))
{
this.send(this.buffer);
}
this.resetInput();
this.submitMessage();
break;
case '!':
if(console.strlen(removeSpaces(this.buffer)) || scope==global_scope)
{
this.bufferKey(key);
}
else
{
scope=global_scope;
case '\x09': /* CTRL-I TAB */
if(message.scope==flag_global) message.scope=flag_normal;
else message.scope=flag_global;
this.printBuffer();
break;
case ';':
this.bufferKey(key);
if(this.buffer.length==1 && fullscreen && user.compare_ars("SYSOP")) {
this.getStringCommand()
this.resetInput();
break;
}
break;
case '@':
if(!user.compare_ars("SYSOP") && !(bbs.sys_status&SS_TMPSYSOP))
break;
if(!user.compare_ars("SYSOP") && !(bbs.sys_status&SS_TMPSYSOP)) break;
default:
if(key) this.bufferKey(key);
this.bufferKey(key);
break;
}
return true;
}
this.drawLines=function()
this.getStringCommand=function()
{
if(!this.lined) return;
drawLine(this.input_line.x-1,this.input_line.y-1,this.columns+2,"\1k\1h");
if(this.y>1) drawLine(this.x-1,this.y-1,this.columns+2);
if(this.input_line.y<24) drawLine(this.input_line.x-1,this.input_line.y+1,this.columns+2,"\1k\1h");
var cmd=console.getstr();
if(cmd.length>0) {
str_cmds(cmd);
return true;
} else return false;
}
this.drawBox=function()
this.submitMessage=function()
{
if(!this.boxed) return;
console.gotoxy(this.x-1,this.y-1);
console.putmsg("\1n\1h\xDA");
drawLine(false,false,this.columns-(8+this.room.length),"\1n\1h");
console.putmsg("\1n\1h\xB4\1nCHAT\1h: \1n" + this.room + "\1h\xC3\xBF");
for(line = 0; line<this.rows; line++)
{
console.gotoxy(this.x-1,this.y+line);
printf("\1n\1h\xB3%*s\xB3",this.columns,"");
if(strlen(this.buffer)>0) {
this.send(this.buffer,message.level,message.scope,message.source,message.target);
switch(message.scope)
{
case flag_global:
this.display(this.buffer,global_color,user.alias);
break;
case flag_private:
this.display(this.buffer,private_color,user.alias,message.target);
break;
case flag_normal:
default:
this.display(this.buffer,local_color,user.alias);
break;
}
}
console.gotoxy(this.input_line.x-1,this.input_line.y-1);
console.putmsg("\1n\1h\xC3");
drawLine(false,false,this.columns-7,"\1n\1h");
console.putmsg("\1n\1h\xB4\1nINPUT\1h\xC3\xB4");
console.gotoxy(this.input_line.x-1,this.input_line.y);
printf("\1n\1h\xB3%*s\xB3",this.columns,"");
console.gotoxy(this.input_line.x-1,this.input_line.y+1);
console.putmsg("\1n\1h\xC0");
drawLine(false,false,this.columns,"\1n\1h");
var spot=console.getxy();
if(!(spot.y==console.screen_rows && spot.x==console.screen_columns)) console.putmsg("\1n\1h\xD9");
this.resetInput();
}
this.backSpace=function()
{
if(this.buffer.length>0)
{
write(console.ansi(ANSI_NORMAL));
this.buffer=this.buffer.substring(0,this.buffer.length-1);
if(this.fullscreen)
{
if(this.buffer.length>0) {
if(fullscreen) {
console.left();
console.cleartoeol();
this.buffer=this.buffer.substr(0,this.buffer.length-1);
} else if(this.buffer.length<=this.input_line.width) {
this.getInputPosition();
console.left();
console.putmsg(" ",P_SAVEATR);
this.buffer=this.buffer.substr(0,this.buffer.length-1);
} else {
this.buffer=this.buffer.substr(0,this.buffer.length-1);
this.printBuffer();
}
this.bufferKey();
return true;
} else {
return false;
}
}
this.bufferKey=function(key) //ADD A KEY TO THE USER INPUT BUFFER
this.getInputPosition=function()
{
if(!this.fullscreen)
{
var offset=key?1:0;
if(this.buffer.length+offset>this.columns)
{
var overrun=(this.buffer.length+offset-this.columns);
console.gotoxy(this.input_line.x+this.buffer.length,this.input_line.y);
}
this.printBuffer=function()
{
if(!this.buffer.length) return false;
var color="";
switch(message.scope) {
case flag_global:
color=background + global_color;
break;
case flag_private:
color=background + private_color;
break;
case flag_normal:
default:
color=background + input_color;
break;
}
if(fullscreen) {
console.putmsg(color,P_SAVEATR);
console.write("\r" + this.buffer);
console.cleartoeol();
} else {
console.gotoxy(this.input_line);
console.putmsg(color,P_SAVEATR);
if(this.buffer.length>this.input_line.width) {
var overrun=(this.buffer.length-this.columns);
var truncated=this.buffer.substr(overrun);
var disp=truncated;
if(disp.indexOf('@')>=0) disp=disp.replace(/@/g,"?");
console.gotoxy(this.input_line.x,this.input_line.y);
console.putmsg(input_color + disp,P_SAVEATR);
}
else if(!key)
{
console.gotoxy(this.input_line.x,this.input_line.y);
var disp=this.buffer;
if(disp.indexOf('@')>=0) disp=disp.replace(/@/g,"?");
console.putmsg(input_color + disp,P_SAVEATR);
}
else
{
offset=this.buffer.length;
console.gotoxy(this.input_line.x+offset,this.input_line.y);
console.write(disp);
} else {
console.write(this.buffer);
}
}
if(key)
{
this.buffer+=key;
if(key=="@") key="?";
console.putmsg(input_color + key,P_SAVEATR);
}
if(!this.fullscreen && this.buffer.length<this.columns) clearLine(this.columns-this.buffer.length);
}
this.display=function(text,color,username)
this.bufferKey=function(key) //ADD A KEY TO THE USER INPUT BUFFER
{
var col=color?color:"";
//FOR FULLSCREEN MODE WITH NO INPUT LINE, DISPLAY MESSAGE IN FULL AND RETURN
if(this.fullscreen)
{
if(!text) return;
if(username) console.putmsg("\r" + col + username + ": " + text + "\r\n",P_SAVEATR);
else console.putmsg("\r" + col + text + "\r\n",P_SAVEATR);
if(this.buffer.length) console.putmsg(local_color+this.buffer,P_SAVEATR);
if(!key) return false;
var color="";
switch(message.scope) {
case flag_global:
color=background + global_color;
break;
case flag_private:
color=background + private_color;
break;
case flag_normal:
default:
color=background + input_color;
break;
}
else
{
//FOR ALL OTHER MODES, STORE MESSAGES IN AN ARRAY AND HANDLE WRAPPING
var output=[];
if(text)
{
if(username)
{
messages.push(col + username+ "\1h: " + col + text);
}
else messages.push(col + text);
}
for(msg in messages)
{
var array=this.concat(messages[msg]);
for(item in array)
{
output.push(array[item]);
}
if(!fullscreen) {
if(this.buffer.length>=this.input_line.width) {
this.buffer+=key;
this.printBuffer();
return;
} else {
this.getInputPosition();
}
if(output.length>this.rows && this.scrollbar)
{
this.scrollbar.draw(1,1); //SHOW SCROLLBAR AT BOTTOM LIMIT
this.history_index=0;
while(output.length>this.rows) output.shift();
}
console.gotoxy(this.x,this.y);
for(line in output)
}
this.buffer+=key;
console.putmsg(color,P_SAVEATR);
console.write(key);
}
this.showHistory=function(key) //ACTIVATE MESSAGE HISTORY SCROLLBACK
{
if(!fullscreen && window.length>window.height) {
switch(key)
{
//TODO: FIX SINGLE LINE MODE... NOT FUNCTIONAL
if(this.rows==1) console.gotoxy(this.x,this.y);
else console.gotoxy(this.x,this.y+parseInt(line,10));
var display=output[line];
if(user.compare_ars("SYSOP"))
{
if(display.indexOf('@')>=0) display=display.replace(/@/g,"?");
}
console.putmsg(display,P_SAVEATR);
var length=console.strlen(strip_ctrl(output[line]));
if(length<this.columns) clearLine(this.columns-length);
case '\x02': /* CTRL-B KEY_HOME */
window.home();
break;
case '\x05': /* CTRL-E KEY_END */
window.end();
break;
case KEY_DOWN:
window.scroll(1);
break;
case KEY_UP:
window.scroll(-1);
break;
}
window.draw(this.x,this.y);
scrollbar.draw(window.index,window.length,window.height);
}
}
this.concat=function(text) //WRAP AND CONCATENATE NEW MESSAGE DATA
this.display=function(text,color,source,target)
{
var newarray=[];
if(console.strlen(text)<=this.columns) newarray.push(text);
else
{
var array=word_wrap(text,this.columns,text.length,false);
array=array.split(/[\r\n$]+/);
for(item in array)
{
if(array[item]!=="") newarray.push(removeSpaces(array[item]));
}
var msg;
if(source) {
msg="\r" + color + source + "\1h: " + color + text + "\r\n";
} else {
msg="\r" + color + text + "\r\n";
}
if(fullscreen) {
console.putmsg(msg,P_SAVEATR);
this.printBuffer();
} else {
window.putmsg(false,false,msg,undefined,true);
window.draw(this.x,this.y);
if(window.length>window.height) scrollbar.draw(window.index,window.length,window.height);
}
return newarray;
}
this.processData=function(data)
{
var intensity="";
if(data.name==user.alias) intensity="\1h";
if(ignore[data.source]==true) return false;
switch(data.scope)
{
case normal_scope:
if(data.name) this.display(data.message,remote_color + intensity,data.name);
else this.display(data.message,alert_color);
break;
case priv_scope:
this.display(data.message,private_color + intensity,data.name);
break;
case global_scope:
this.display(data.message,global_color + intensity,data.name);
break;
default:
log("message scope unknown");
break;
case flag_private:
if(data.target==user.alias) this.display(data.message,private_color + "\1h",data.source);
break;
case flag_global:
this.display(data.message,global_color + "\1h",data.source);
break;
case flag_normal:
default:
if(!data.source) {
switch(data.level)
{
case flag_alert:
this.display(data.message,alert_color);
break;
case flag_notice:
default:
this.display(data.message,notice_color);
break;
}
} else if(data.source==user.alias) {
this.display(data.message,local_color,data.source);
} else this.display(data.message,remote_color,source);
break;
}
}
this.packageData=function(message)
{
var data=
{
"scope":scope,
"system":system.qwk_id,
"name":user.alias,
"message":message
};
var packet=
{
"scope":scope,
"room":this.room,
"type":"chat",
"data":data
};
this.processData(data);
return packet;
}
this.resetInput=function()
{
if(!this.fullscreen) this.input_line.clear();
else
{
if(!fullscreen) this.input_line.clear();
else {
console.left(this.buffer.length);
console.cleartoeol();
}
this.buffer="";
scope=normal_scope;
message=new Message();
}
}
function Message(txt,level,scope,source,target)
{
this.txt=txt;
this.level=level;
this.scope=scope;
this.source=source;
this.target=target;
}
function InputLine(x,y,width,bg)
{
this.x=x;
this.y=y;
this.width=width;
this.bg=bg;
this.position;
this.window;
this.buffer="";
this.clear=function(bg)
this.clear=function(bg)
{
clearLine(this.width,this.x,this.y,bg?bg:this.bg);
console.gotoxy(this);
}
this.init=function(x,y,w,bg,window)
{
this.x=x;
this.y=y;
this.width=w;
this.bg=bg;
if(window) {
this.window=new Window(x,y,w,3);
this.window.init("\1nINPUT");
this.x+=1;
this.y+=1;
this.width-=2;
}
}
this.draw=function()
{
if(this.window) {
this.window.draw();
}
console.gotoxy(this.x,this.y);
console.write(printPadded(this.color + this.buffer,this.width));
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment