mirror of
https://github.com/PurpleI2P/i2pd-tools.git
synced 2025-01-22 13:27:17 +01:00
commit
db9b142cfb
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -9,6 +9,7 @@
|
|||
keygen
|
||||
keyinfo
|
||||
famtool
|
||||
i2pbase64
|
||||
regaddr
|
||||
routerinfo
|
||||
vain
|
||||
|
|
25
Makefile
25
Makefile
|
@ -8,6 +8,8 @@ FLAGS = -Wall -std=c++11 -Wno-misleading-indentation
|
|||
|
||||
ifeq ($(UNAME),Linux)
|
||||
FLAGS += -g
|
||||
else ifeq ($(UNAME),FreeBSD)
|
||||
FLAGS += -g
|
||||
else
|
||||
# Win32
|
||||
FLAGS += -Os -D_MT -DWIN32 -D_WINDOWS -DWIN32_LEAN_AND_MEAN
|
||||
|
@ -16,11 +18,14 @@ endif
|
|||
|
||||
INCFLAGS = -I$(LIBI2PD_PATH) -I$(LIBI2PD_CLIENT_PATH) -I$(I2PD_PATH)
|
||||
CXXFLAGS = $(FLAGS)
|
||||
LDFLAGS = -Wl,-rpath,/usr/local/lib
|
||||
LDFLAGS =
|
||||
LIBS = $(I2PD_PATH)/libi2pd.a -lboost_system$(BOOST_SUFFIX) -lboost_date_time$(BOOST_SUFFIX) -lboost_filesystem$(BOOST_SUFFIX) -lboost_program_options$(BOOST_SUFFIX) -lssl -lcrypto -lz
|
||||
|
||||
ifeq ($(UNAME),Linux)
|
||||
LIBS += -lrt -lpthread
|
||||
else ifeq ($(UNAME),FreeBSD)
|
||||
FLAGS += -lrt -lpthread
|
||||
LDFLAGS += -Wl,-rpath,/usr/local/lib
|
||||
else
|
||||
# Win32
|
||||
LIBS += -lws2_32 -lwsock32 -lgdi32 -liphlpapi -lstdc++ -lpthread
|
||||
|
@ -32,26 +37,29 @@ OBJECTS = $(SOURCES:.cpp=.o)
|
|||
I2PD_LIB = libi2pd.a
|
||||
|
||||
|
||||
all: keygen keyinfo famtool routerinfo regaddr vain
|
||||
all: keygen keyinfo famtool routerinfo regaddr vain i2pbase64
|
||||
|
||||
routerinfo: $(OBJECTS)
|
||||
$(CXX) -o routerinfo routerinfo.o $(LDFLAGS) $(LIBS)
|
||||
$(CXX) -o routerinfo routerinfo.o $(LDFLAGS) $(LIBS)
|
||||
|
||||
keygen: $(OBJECTS)
|
||||
$(CXX) -o keygen keygen.o $(LDFLAGS) $(LIBS)
|
||||
$(CXX) -o keygen keygen.o $(LDFLAGS) $(LIBS)
|
||||
|
||||
keyinfo: $(OBJECTS)
|
||||
$(CXX) -o keyinfo keyinfo.o $(LDFLAGS) $(LIBS)
|
||||
$(CXX) -o keyinfo keyinfo.o $(LDFLAGS) $(LIBS)
|
||||
|
||||
famtool: $(OBJECTS)
|
||||
$(CXX) -o famtool famtool.o $(LDFLAGS) $(LIBS)
|
||||
$(CXX) -o famtool famtool.o $(LDFLAGS) $(LIBS)
|
||||
|
||||
regaddr: $(OBJECTS)
|
||||
$(CXX) -o regaddr regaddr.o $(LDFLAGS) $(LIBS)
|
||||
$(CXX) -o regaddr regaddr.o $(LDFLAGS) $(LIBS)
|
||||
|
||||
vain: $(OBJECTS)
|
||||
$(CXX) -o vain vanitygen.o $(LDFLAGS) $(LIBS)
|
||||
|
||||
i2pbase64: $(OBJECTS)
|
||||
$(CXX) -o i2pbase64 i2pbase64.o $(LDFALGS) $(LIBS)
|
||||
|
||||
$(OBJECTS): libi2pd.a
|
||||
|
||||
.SUFFIXES:
|
||||
|
@ -73,7 +81,8 @@ clean-obj:
|
|||
rm -f $(OBJECTS)
|
||||
|
||||
clean-bin:
|
||||
rm -f keyinfo keygen famtool regaddr routerinfo vain
|
||||
rm -f keyinfo keygen famtool regaddr routerinfo i2pbase64 vain
|
||||
|
||||
|
||||
clean: clean-i2pd clean-obj clean-bin
|
||||
|
||||
|
|
85
i2pbase64.cpp
Normal file
85
i2pbase64.cpp
Normal file
|
@ -0,0 +1,85 @@
|
|||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <functional>
|
||||
#include <cassert>
|
||||
#include "Base.h"
|
||||
|
||||
const size_t BUFFSZ = 1024;
|
||||
|
||||
static int printHelp(const char * exe, int exitcode)
|
||||
{
|
||||
std::cout << "usage: " << exe << " [-d] [filename]" << std::endl;
|
||||
return exitcode;
|
||||
}
|
||||
|
||||
template <typename InCh, typename OutCh, size_t isz, size_t osz>
|
||||
static int operate(std::function<std::size_t(const InCh *, size_t, OutCh *, size_t)> f, int infile, int outfile)
|
||||
{
|
||||
InCh inbuf[isz];
|
||||
OutCh outbuf[osz];
|
||||
ssize_t sz;
|
||||
size_t outsz;
|
||||
while((sz = read(infile, inbuf, sizeof(inbuf))) > 0)
|
||||
{
|
||||
outsz = f(inbuf, sz, outbuf, sizeof(outbuf));
|
||||
if(outsz && outsz <= sizeof(outbuf))
|
||||
{
|
||||
write(outfile, outbuf, outsz);
|
||||
}
|
||||
else
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
return errno;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
int main(int argc, char * argv[])
|
||||
{
|
||||
int opt;
|
||||
bool decode = false;
|
||||
int infile = 0;
|
||||
while((opt = getopt(argc, argv, "dh")) != -1)
|
||||
{
|
||||
switch(opt)
|
||||
{
|
||||
case 'h':
|
||||
return printHelp(argv[0], 0);
|
||||
case 'd':
|
||||
decode = true;
|
||||
break;
|
||||
default:
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (argc - optind > 1)
|
||||
{
|
||||
return printHelp(argv[0], -1);
|
||||
}
|
||||
|
||||
if (optind < argc)
|
||||
{
|
||||
infile = open(argv[optind], O_RDONLY);
|
||||
if(infile == -1) {
|
||||
perror(argv[optind]);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
int retcode = 0;
|
||||
if(decode)
|
||||
{
|
||||
retcode = operate<char, uint8_t, BUFFSZ*4, BUFFSZ*3>(i2p::data::Base64ToByteStream, infile, 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
retcode = operate<uint8_t, char, BUFFSZ*3, BUFFSZ*4>(&i2p::data::ByteStreamToBase64, infile, 1);
|
||||
}
|
||||
close(infile);
|
||||
return retcode;
|
||||
}
|
17
websocks-demo/Makefile
Normal file
17
websocks-demo/Makefile
Normal file
|
@ -0,0 +1,17 @@
|
|||
WEBSOCKS_SRC = websocks.js
|
||||
BT_OUT = websocks-bt.js
|
||||
BT_SRC = bittorrent.js
|
||||
|
||||
IRC_OUT = websocks-irc.js
|
||||
IRC_SRC = irc-client.js
|
||||
|
||||
all: $(BT_OUT) $(IRC_OUT)
|
||||
|
||||
$(IRC_OUT):
|
||||
browserify $(WEBSOCKS_SRC) $(IRC_SRC) -o $(IRC_OUT)
|
||||
|
||||
$(BT_OUT):
|
||||
browserify $(WEBSOCKS_SRC) $(BT_SRC) -o $(BT_OUT)
|
||||
|
||||
clean:
|
||||
rm -f $(BT_OUT) $(IRC_OUT)
|
12
websocks-demo/bittorrent-client.html
Normal file
12
websocks-demo/bittorrent-client.html
Normal file
|
@ -0,0 +1,12 @@
|
|||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<title> bittorrent over i2p with WebSOCKS </title>
|
||||
<script src="websocks-bt.js" type="text/javascript"></script>
|
||||
<link rel="stylesheet" href="style.css"></link>
|
||||
</head>
|
||||
<body>
|
||||
<label for="ws-server">WebSOCKS server:</label><input id="ws-server" value="ws://127.0.0.1:7766/"></input>
|
||||
<label for="torrent-file">Torrent File:</label><input type="file" id="torrent-file" />
|
||||
<button onclick="start_downloading()">start</button>
|
||||
</html>
|
23
websocks-demo/bittorrent.js
Normal file
23
websocks-demo/bittorrent.js
Normal file
|
@ -0,0 +1,23 @@
|
|||
var Protocol = require('bittorrent-protocol');
|
||||
var stream = require('stream');
|
||||
var WebSocks = require("./websocks.js").WebSocks;
|
||||
|
||||
|
||||
function start_torrent(torrent_file_blob)
|
||||
{
|
||||
var torrent = new WebsocksTorrent();
|
||||
var elem = document.getElementById("ws-server");
|
||||
torrent.start(elem.value);
|
||||
torrent.addTorrent(torrent_file_blob);
|
||||
}
|
||||
|
||||
function start_downloading()
|
||||
{
|
||||
var elem = document.getElementById("torrent-file");
|
||||
var files = elem.files;
|
||||
for (var f of files) {
|
||||
if(f.slice) {
|
||||
start_torrent(f.slice());
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,14 +1,10 @@
|
|||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<title> irc client with WebSOCKS </title>
|
||||
<script src="websocks.js" type="text/javascript"></script>
|
||||
<link rel="stylesheet" href="style.css"></link>
|
||||
<title> websocks demos </title>
|
||||
</head>
|
||||
<body>
|
||||
<label for="ws-server">WebSOCKS server:</label><input id="ws-server" value="ws://127.0.0.1:7766/"></input>
|
||||
<input id="irc-server" value="irc.dg.i2p"></input>
|
||||
<button onclick="ws_try_connect()">connect</button>
|
||||
<div id="irc-window">
|
||||
</div>
|
||||
<a href="irc-client.html">irc client demo</a>
|
||||
<a href="bittorrent-client.html">bittorrent client demo</a>
|
||||
</body>
|
||||
</html>
|
||||
|
|
14
websocks-demo/irc-client.html
Normal file
14
websocks-demo/irc-client.html
Normal file
|
@ -0,0 +1,14 @@
|
|||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<title> irc client with WebSOCKS </title>
|
||||
<link rel="stylesheet" href="style.css"></link>
|
||||
</head>
|
||||
<body>
|
||||
<label for="ws-server">WebSOCKS server:</label><input id="ws-server" value="ws://127.0.0.1:7766/"></input>
|
||||
<input id="irc-server" value="irc.dg.i2p"></input>
|
||||
<button id="connect">connect</button>
|
||||
<div id="irc-window">
|
||||
</div>
|
||||
<script src="websocks-irc.js" type="text/javascript"></script>
|
||||
</html>
|
292
websocks-demo/irc-client.js
Normal file
292
websocks-demo/irc-client.js
Normal file
|
@ -0,0 +1,292 @@
|
|||
var WebSocks = require("./websocks.js").WebSocks;
|
||||
|
||||
|
||||
function ws_try_connect()
|
||||
{
|
||||
|
||||
var elem = document.getElementById("irc-window");
|
||||
elem.remove();
|
||||
elem = document.createElement("div");
|
||||
elem.id ="irc-window";
|
||||
document.body.appendChild(elem);
|
||||
|
||||
var input = document.createElement("input");
|
||||
input.setAttribute("class", "text-input");
|
||||
elem.appendChild(input);
|
||||
|
||||
|
||||
var irc = {
|
||||
connected: 0,
|
||||
line_in: "",
|
||||
target: "",
|
||||
nick: "ebin",
|
||||
panes: {}
|
||||
};
|
||||
|
||||
function irc_ui_show_pane(pane)
|
||||
{
|
||||
irc_ui_ensure_pane(pane);
|
||||
// hide all other panes
|
||||
for (var k in irc.panes) {
|
||||
if(k == pane) {
|
||||
irc.panes[k].elem.style = "display: inline-block";
|
||||
irc.target = k;
|
||||
} else {
|
||||
irc.panes[k].elem.style = "display: none";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function irc_ui_ensure_pane(pane)
|
||||
{
|
||||
if(irc.panes[pane]) return;
|
||||
var e = document.createElement("pre");
|
||||
e.setAttribute("class", "text-window");
|
||||
e.style = "display: none";
|
||||
e.setAttribute("panename", pane);
|
||||
irc.panes[pane] = {
|
||||
elem: e,
|
||||
name: pane
|
||||
};
|
||||
var root = document.getElementById("irc-window");
|
||||
root.appendChild(e);
|
||||
}
|
||||
|
||||
function irc_ui_println(line, pane)
|
||||
{
|
||||
if(line == "") return;
|
||||
var node = document.createTextNode(line);
|
||||
var e = document.createElement("div");
|
||||
e.appendChild(node);
|
||||
if(!pane) {
|
||||
pane = " ";
|
||||
}
|
||||
irc_ui_ensure_pane(pane);
|
||||
var p = irc.panes[pane];
|
||||
if(p) {
|
||||
p.elem.appendChild(e);
|
||||
if (pane == irc.target) {
|
||||
window.scroll(0, p.elem.offsetTop + p.elem.offsetHeight);
|
||||
}
|
||||
} else {
|
||||
console.log("No pane called "+pane);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function irc_on_privmsg(src, target, msg)
|
||||
{
|
||||
var parts = src.split("!");
|
||||
src = parts[0].slice(1);
|
||||
irc_ui_println("<"+src+ "> "+msg, target);
|
||||
}
|
||||
|
||||
function irc_on_greeted(conn)
|
||||
{
|
||||
irc_ui_println("successfully joined irc");
|
||||
}
|
||||
|
||||
function irc_on_join(src, target)
|
||||
{
|
||||
irc_ui_println("--> "+src, target);
|
||||
}
|
||||
|
||||
function irc_on_part(src, target)
|
||||
{
|
||||
irc_ui_println("<-- "+src, target);
|
||||
}
|
||||
|
||||
function irc_on_other(src, cmd, target, msg)
|
||||
{
|
||||
irc_ui_println("<"+src+"> "+msg, src);
|
||||
}
|
||||
|
||||
function irc_process_in(conn)
|
||||
{
|
||||
var line = irc.line_in.trim();
|
||||
console.log("--> "+line);
|
||||
if(line.startsWith("PING ")) {
|
||||
// handle ping
|
||||
irc_sendline(conn, "PONG "+line.slice(5));
|
||||
return;
|
||||
}
|
||||
var parts = line.split(" ");
|
||||
if (parts.length > 2) {
|
||||
var src = parts[0];
|
||||
var cmd = parts[1];
|
||||
var target = parts[2];
|
||||
var idx = line.indexOf(target);
|
||||
var msg = line.slice(idx+target.length+2);
|
||||
if (cmd == "PRIVMSG") {
|
||||
irc_on_privmsg(src, target, msg);
|
||||
return;
|
||||
}
|
||||
if (cmd == "JOIN" ) {
|
||||
irc_on_join(src, target);
|
||||
return;
|
||||
}
|
||||
if (cmd == "PART") {
|
||||
irc_on_part(src, target);
|
||||
return;
|
||||
}
|
||||
|
||||
if(cmd == "PONG") return;
|
||||
if(cmd == "376") {
|
||||
// we have been greeted fully
|
||||
irc_on_greeted(conn);
|
||||
return;
|
||||
}
|
||||
if (cmd == "433") {
|
||||
irc.nick = irc.nick + "_";
|
||||
irc_sendline(conn, "NICK "+irc.nick);
|
||||
irc_sendline(conn, "USER "+irc.nick+" "+irc.nick+" "+irc.nick+" :"+irc.nick);
|
||||
}
|
||||
irc_on_other(src.slice(1), cmd, target, msg);
|
||||
}
|
||||
irc_ui_println(line);
|
||||
}
|
||||
|
||||
function irc_data(conn, data)
|
||||
{
|
||||
data = irc.line_in + data;
|
||||
var lines = data.split("\n");
|
||||
for(var idx = 0; idx < lines.length; idx++) {
|
||||
irc.line_in = lines [idx] + "\n";
|
||||
irc_process_in(conn);
|
||||
}
|
||||
}
|
||||
|
||||
function irc_sendline(conn, line)
|
||||
{
|
||||
console.log("<-- "+ line);
|
||||
conn.write(line + "\n");
|
||||
}
|
||||
|
||||
function irc_privmsg(conn, target, msg)
|
||||
{
|
||||
irc_ui_println("<"+irc.nick+"> "+msg, target);
|
||||
irc_sendline(conn, "PRIVMSG "+target+" :"+msg);
|
||||
}
|
||||
|
||||
function irc_join_channel(conn, chnl)
|
||||
{
|
||||
irc_sendline(conn, "JOIN "+chnl);
|
||||
irc_ui_ensure_pane(chnl);
|
||||
}
|
||||
|
||||
function handle_input_command(conn, arg, params)
|
||||
{
|
||||
arg = arg.toLowerCase();
|
||||
if (arg == "j" || arg == "join") {
|
||||
for (var idx = 0 ; idx < params.length; idx ++) {
|
||||
irc_join_channel(conn, params[idx]);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if(arg == "lp" || arg == "listpanes") {
|
||||
irc_ui_println("--- begin list of panes", irc.target);
|
||||
for (var k in irc.panes) {
|
||||
if(k == irc.target) {
|
||||
irc_ui_println("(active) : "+k, irc.target);
|
||||
} else {
|
||||
irc_ui_println(" : "+k, irc.target);
|
||||
}
|
||||
}
|
||||
irc_ui_println("--- end list of panes", irc.target);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if(arg == "m" || arg == "msg") {
|
||||
irc_privmsg(conn, params[0], params.slice(1).join(" "));
|
||||
return;
|
||||
}
|
||||
|
||||
if(arg == "n" || arg == "nick") {
|
||||
irc_sendline(conn, "NICK "+params[0]);
|
||||
irc.nick = params[0];
|
||||
return;
|
||||
}
|
||||
if(arg == "r" || arg == "raw") {
|
||||
irc_sendline(conn, params.join(" "));
|
||||
return;
|
||||
}
|
||||
if(arg == "q" || arg == "quit") {
|
||||
irc_sendline(conn, "QUIT");
|
||||
return;
|
||||
}
|
||||
if(arg == "w" || arg == "window") {
|
||||
irc.target = params[0];
|
||||
irc_ui_show_pane(irc.target);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
function handle_input_line(conn, line)
|
||||
{
|
||||
if(line[0] == "/") {
|
||||
var parts = line.split(" ");
|
||||
handle_input_command(conn, parts[0].slice(1), parts.slice(1));
|
||||
} else {
|
||||
irc_privmsg(conn, irc.target, line);
|
||||
}
|
||||
};
|
||||
|
||||
function irc_connected(conn, url)
|
||||
{
|
||||
irc.connected = 1;
|
||||
console.log("connected to irc");
|
||||
irc_ui_println("connecting to "+url+"...");
|
||||
// send user command
|
||||
irc_sendline(conn, "NICK "+irc.nick);
|
||||
irc_sendline(conn, "USER "+irc.nick+" "+irc.nick+" "+irc.nick+" :"+irc.nick);
|
||||
irc.pinger = setInterval(function(){
|
||||
if(irc.connected) {
|
||||
irc_sendline(conn, "PING :i-hate-tcp-lol-"+new Date().getTime());
|
||||
}
|
||||
}, 10000);
|
||||
input.addEventListener("keypress", function(ev){
|
||||
// handle enter key
|
||||
switch(ev.key) {
|
||||
case "Enter":
|
||||
handle_input_line(conn, input.value);
|
||||
ev.preventDefault();
|
||||
input.value = "";
|
||||
}
|
||||
return;
|
||||
});
|
||||
}
|
||||
|
||||
var e = document.getElementById("ws-server");
|
||||
var wsurl = e.value;
|
||||
e = document.getElementById("irc-server");
|
||||
var irc_url = e.value;
|
||||
|
||||
var parts = irc_url.split(":");
|
||||
var host = parts[0];
|
||||
var port = 6667;
|
||||
if(parts.length != 1) {
|
||||
port = parts[1];
|
||||
}
|
||||
|
||||
irc_ui_show_pane(" ");
|
||||
|
||||
var sock = new WebSocks(wsurl);
|
||||
|
||||
sock.connect(host, port, function(err, writer, reader) {
|
||||
if(err) {
|
||||
console.log(err);
|
||||
} else {
|
||||
irc_connected(writer);
|
||||
reader.on("data", function(data) {
|
||||
irc_data(writer, data);
|
||||
});
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
document.getElementById("connect").onclick = function() {
|
||||
console.log("try connect");
|
||||
ws_try_connect();
|
||||
};
|
15
websocks-demo/readme.md
Normal file
15
websocks-demo/readme.md
Normal file
|
@ -0,0 +1,15 @@
|
|||
# demos
|
||||
|
||||
## dependencies
|
||||
|
||||
* browserify
|
||||
* GNU Make
|
||||
* i2pd with websockets enabled
|
||||
* websocks tunnel
|
||||
|
||||
## usage:
|
||||
|
||||
make
|
||||
python3 -m http.server 3000
|
||||
|
||||
then go [here](http://127.0.0.1:3000/)
|
7478
websocks-demo/websocks-bt.js
Normal file
7478
websocks-demo/websocks-bt.js
Normal file
File diff suppressed because it is too large
Load diff
5828
websocks-demo/websocks-irc.js
Normal file
5828
websocks-demo/websocks-irc.js
Normal file
File diff suppressed because it is too large
Load diff
|
@ -1,293 +1,137 @@
|
|||
var stream = require('stream');
|
||||
|
||||
function ws_try_connect()
|
||||
|
||||
function WebSocks(wsurl)
|
||||
{
|
||||
this._wsurl = wsurl;
|
||||
this._ws = null;
|
||||
this._ouraddr = null;
|
||||
this._remoteAddr = null;
|
||||
this._recvbuffer = stream.PassThrough();
|
||||
this._sendbuffer = stream.PassThrough();
|
||||
}
|
||||
|
||||
WebSocks.prototype.createListener = function(callback) {
|
||||
var self = this;
|
||||
self._doAccept(function(err) {
|
||||
if(err) callback(err, null);
|
||||
else {
|
||||
callback(null, self._sendbuffer, self._recvbuffer);
|
||||
}
|
||||
}, function(data) {
|
||||
self._recvbuffer.write(data);
|
||||
});
|
||||
};
|
||||
|
||||
var elem = document.getElementById("irc-window");
|
||||
elem.remove();
|
||||
elem = document.createElement("div");
|
||||
elem.id ="irc-window";
|
||||
document.body.appendChild(elem);
|
||||
|
||||
var input = document.createElement("input");
|
||||
input.setAttribute("class", "text-input");
|
||||
elem.appendChild(input);
|
||||
|
||||
|
||||
var irc = {
|
||||
connected: 0,
|
||||
line_in: "",
|
||||
target: "",
|
||||
nick: "ebin",
|
||||
panes: {},
|
||||
};
|
||||
|
||||
function irc_ui_show_pane(pane)
|
||||
{
|
||||
irc_ui_ensure_pane(pane);
|
||||
// hide all other panes
|
||||
for (var k in irc.panes) {
|
||||
if(k == pane) {
|
||||
irc.panes[k].elem.style = "display: inline-block";
|
||||
irc.target = k;
|
||||
} else {
|
||||
irc.panes[k].elem.style = "display: none";
|
||||
WebSocks.prototype._doAccept = function(accept_cb, recv_cb) {
|
||||
var self = this;
|
||||
self._socket(function (err, data) {
|
||||
if(!self._remoteAddr)
|
||||
{
|
||||
if(!data)
|
||||
{
|
||||
// send handshake
|
||||
self._ws.send("accept");
|
||||
}
|
||||
else
|
||||
{
|
||||
// this means handshake read
|
||||
var j = JSON.parse(data);
|
||||
if(j.error) {
|
||||
connect_cb(j.error);
|
||||
} else if(j.success){
|
||||
self._remoteAddr = host;
|
||||
connect_cb(null);
|
||||
}
|
||||
// repeat
|
||||
setTimeout(function() {
|
||||
self._doAccept(connect_cb);
|
||||
}, 10);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function irc_ui_ensure_pane(pane)
|
||||
{
|
||||
if(irc.panes[pane]) return;
|
||||
var e = document.createElement("pre");
|
||||
e.setAttribute("class", "text-window");
|
||||
e.style = "display: none";
|
||||
e.setAttribute("panename", pane);
|
||||
irc.panes[pane] = {
|
||||
elem: e,
|
||||
name: pane,
|
||||
};
|
||||
var root = document.getElementById("irc-window");
|
||||
root.appendChild(e);
|
||||
}
|
||||
|
||||
function irc_ui_println(line, pane)
|
||||
{
|
||||
if(line == "") return;
|
||||
var node = document.createTextNode(line);
|
||||
var e = document.createElement("div");
|
||||
e.appendChild(node);
|
||||
if(!pane) {
|
||||
pane = " ";
|
||||
else
|
||||
{
|
||||
recv_cb(err, data);
|
||||
}
|
||||
irc_ui_ensure_pane(pane);
|
||||
var p = irc.panes[pane];
|
||||
if(p) {
|
||||
p.elem.appendChild(e);
|
||||
if (pane == irc.target) {
|
||||
window.scroll(0, p.elem.offsetTop + p.elem.offsetHeight);
|
||||
});
|
||||
};
|
||||
|
||||
WebSocks.prototype._closed = function()
|
||||
{
|
||||
var self = this;
|
||||
self._recvbuffer.close();
|
||||
self._sendbuffer.close();
|
||||
self._ws.close();
|
||||
};
|
||||
|
||||
WebSocks.prototype.connect = function(host, port, connect_cb) {
|
||||
var self = this;
|
||||
self._socket(function (err, data) {
|
||||
if(!self._remoteAddr)
|
||||
{
|
||||
if(!data)
|
||||
{
|
||||
// send handshake
|
||||
self._ws.send("connect "+host+":"+port);
|
||||
}
|
||||
} else {
|
||||
console.log("No pane called "+pane);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function irc_on_privmsg(src, target, msg)
|
||||
{
|
||||
var parts = src.split("!");
|
||||
src = parts[0].slice(1);
|
||||
irc_ui_println("<"+src+ "> "+msg, target);
|
||||
}
|
||||
|
||||
function irc_on_greeted(conn)
|
||||
{
|
||||
irc_ui_println("successfully joined irc");
|
||||
}
|
||||
|
||||
function irc_on_join(src, target)
|
||||
{
|
||||
irc_ui_println("--> "+src, target);
|
||||
}
|
||||
|
||||
function irc_on_part(src, target)
|
||||
{
|
||||
irc_ui_println("<-- "+src, target);
|
||||
}
|
||||
|
||||
function irc_on_other(src, cmd, target, msg)
|
||||
{
|
||||
irc_ui_println("<"+src+"> "+msg, src);
|
||||
}
|
||||
|
||||
function irc_process_in(conn)
|
||||
{
|
||||
var line = irc.line_in.trim();
|
||||
console.log("--> "+line);
|
||||
if(line.startsWith("PING ")) {
|
||||
// handle ping
|
||||
irc_sendline(conn, "PONG "+line.slice(5));
|
||||
return;
|
||||
}
|
||||
var parts = line.split(" ");
|
||||
if (parts.length > 2) {
|
||||
var src = parts[0];
|
||||
var cmd = parts[1];
|
||||
var target = parts[2];
|
||||
var idx = line.indexOf(target);
|
||||
var msg = line.slice(idx+target.length+2);
|
||||
if (cmd == "PRIVMSG") {
|
||||
irc_on_privmsg(src, target, msg);
|
||||
return;
|
||||
}
|
||||
if (cmd == "JOIN" ) {
|
||||
irc_on_join(src, target);
|
||||
return;
|
||||
}
|
||||
if (cmd == "PART") {
|
||||
irc_on_part(src, target);
|
||||
return;
|
||||
}
|
||||
|
||||
if(cmd == "PONG") return;
|
||||
if(cmd == "376") {
|
||||
// we have been greeted fully
|
||||
irc_on_greeted(conn);
|
||||
return;
|
||||
}
|
||||
irc_on_other(src.slice(1), cmd, target, msg);
|
||||
}
|
||||
irc_ui_println(line);
|
||||
}
|
||||
|
||||
function irc_data(conn, data)
|
||||
{
|
||||
data = irc.line_in + data;
|
||||
var lines = data.split("\n");
|
||||
for(var idx = 0; idx < lines.length; idx++) {
|
||||
irc.line_in = lines [idx] + "\n";
|
||||
irc_process_in(conn);
|
||||
}
|
||||
}
|
||||
|
||||
function irc_sendline(conn, line)
|
||||
{
|
||||
console.log("<-- "+ line);
|
||||
conn.send(line + "\n");
|
||||
}
|
||||
|
||||
function irc_privmsg(conn, target, msg)
|
||||
{
|
||||
irc_ui_println("<"+irc.nick+"> "+msg, target);
|
||||
irc_sendline(conn, "PRIVMSG "+target+" :"+msg);
|
||||
}
|
||||
|
||||
function irc_join_channel(conn, chnl)
|
||||
{
|
||||
irc_sendline(conn, "JOIN "+chnl);
|
||||
irc_ui_ensure_pane(chnl);
|
||||
}
|
||||
|
||||
function handle_input_command(conn, arg, params)
|
||||
{
|
||||
arg = arg.toLowerCase();
|
||||
if (arg == "j" || arg == "join") {
|
||||
for (var idx = 0 ; idx < params.length; idx ++) {
|
||||
irc_join_channel(conn, params[idx]);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if(arg == "lp" || arg == "listpanes") {
|
||||
irc_ui_println("--- begin list of panes", irc.target);
|
||||
for (var k in irc.panes) {
|
||||
if(k == irc.target) {
|
||||
irc_ui_println("(active) : "+k, irc.target);
|
||||
else
|
||||
{
|
||||
// this means handshake read
|
||||
var j = JSON.parse(data);
|
||||
if(j.error) {
|
||||
connect_cb(j.error, null, null);
|
||||
} else if(j.success){
|
||||
self._remoteAddr = host;
|
||||
connect_cb(null, self._sendbuffer, self._recvbuffer);
|
||||
} else {
|
||||
irc_ui_println(" : "+k, irc.target);
|
||||
connect_cb("failed to connect", null, null);
|
||||
}
|
||||
}
|
||||
irc_ui_println("--- end list of panes", irc.target);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if(arg == "m" || arg == "msg") {
|
||||
irc_privmsg(conn, params[0], params.slice(1).join(" "));
|
||||
return;
|
||||
else
|
||||
{
|
||||
self._recvbuffer.write(data);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
if(arg == "n" || arg == "nick") {
|
||||
irc_sendline(conn, "NICK "+params[0]);
|
||||
irc.nick = params[0];
|
||||
return;
|
||||
}
|
||||
if(arg == "r" || arg == "raw") {
|
||||
irc_sendline(conn, params.join(" "));
|
||||
return;
|
||||
}
|
||||
if(arg == "q" || arg == "quit") {
|
||||
irc_sendline(conn, "QUIT");
|
||||
return;
|
||||
}
|
||||
if(arg == "w" || arg == "window") {
|
||||
irc.target = params[0];
|
||||
irc_ui_show_pane(irc.target);
|
||||
return;
|
||||
}
|
||||
}
|
||||
WebSocks.prototype._socket = function(cb) {
|
||||
var self = this;
|
||||
self._ws = new WebSocket(self._wsurl);
|
||||
self._ws.onclose = function(ev) {
|
||||
self._closed();
|
||||
};
|
||||
|
||||
function handle_input_line(conn, line)
|
||||
{
|
||||
if(line[0] == "/") {
|
||||
var parts = line.split(" ");
|
||||
handle_input_command(conn, parts[0].slice(1), parts.slice(1));
|
||||
} else {
|
||||
irc_privmsg(conn, irc.target, line);
|
||||
}
|
||||
}
|
||||
self._ws.onopen = function(ev) {
|
||||
console.log("connected to websocks");
|
||||
self._ws.send("getaddr");
|
||||
};
|
||||
|
||||
function irc_connected(conn, url)
|
||||
{
|
||||
console.log("connected to irc");
|
||||
irc_ui_show_pane(" ");
|
||||
irc_ui_println("connecting to "+url+"...");
|
||||
// send user command
|
||||
irc_sendline(conn, "NICK "+irc.nick);
|
||||
irc_sendline(conn, "USER "+irc.nick+" "+irc.nick+" "+irc.nick+" :"+irc.nick);
|
||||
irc.pinger = setInterval(function(){
|
||||
if(irc.connected) {
|
||||
irc_sendline(conn, "PING :i-hate-tcp-lol-"+new Date().getTime());
|
||||
}
|
||||
}, 10000);
|
||||
input.addEventListener("keypress", function(ev){
|
||||
// handle enter key
|
||||
switch(ev.key) {
|
||||
case "Enter":
|
||||
handle_input_line(conn, input.value);
|
||||
ev.preventDefault();
|
||||
input.value = "";
|
||||
}
|
||||
return;
|
||||
});
|
||||
}
|
||||
|
||||
var e = document.getElementById("ws-server");
|
||||
var ws = new WebSocket(e.value);
|
||||
e = document.getElementById("irc-server");
|
||||
var irc_url = e.value;
|
||||
|
||||
ws.onclose = function(err) {
|
||||
console.log("connection closed "+err);
|
||||
irc.connected = 0;
|
||||
clearInterval(irc.pinger);
|
||||
irc_ui_println("connection closed");
|
||||
}
|
||||
|
||||
ws.onopen = function(ev) {
|
||||
console.log("connect to "+irc_url);
|
||||
irc_ui_println("resolving "+irc_url+" ...");
|
||||
ws.send(irc_url);
|
||||
}
|
||||
ws.onmessage = function(ev) {
|
||||
var data = ev.data;
|
||||
if(irc.connected) {
|
||||
irc_data(ws, data);
|
||||
} else {
|
||||
var j = JSON.parse(data);
|
||||
self._ws.onmessage = function(ev) {
|
||||
if(!self._ouraddr)
|
||||
{
|
||||
var j = JSON.parse(ev.data);
|
||||
if(j.error) {
|
||||
console.log("WebSOCKS error: "+j.error);
|
||||
console.log("try again");
|
||||
setTimeout(function() {
|
||||
ws.send(irc_url);
|
||||
}, 1000);
|
||||
console.log("connect error: "+j.error);
|
||||
cb(j.error, null);
|
||||
return;
|
||||
}
|
||||
irc.connected = j.success == "1";
|
||||
if(irc.connected) {
|
||||
irc_connected(ws, irc_url);
|
||||
if(j.success && j.destination) {
|
||||
self._ouraddr = j.destination;
|
||||
} else {
|
||||
cb("failed to connect", null);
|
||||
return;
|
||||
}
|
||||
self._sendbuffer.on("data", function(data) {
|
||||
self._ws.send(data);
|
||||
});
|
||||
cb(null, null);
|
||||
}
|
||||
}
|
||||
else
|
||||
cb(null, ev.data);
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
module.exports = {
|
||||
"WebSocks": WebSocks,
|
||||
};
|
||||
|
|
Loading…
Reference in a new issue