forked from JanKlopper/pixelvloed
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathclient.js
186 lines (163 loc) · 4.83 KB
/
client.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
// Install nodejs nodejs-legacy
// Install npm
// with npm install jspack
// with npm install sleep
// imports
var dgram = require('dgram');
var struct = require('jspack')['jspack'];
var sleep = require('sleep');
// static vars
var PROTOCOL_PREAMBLE = 'pixelvloed';
var DISCOVER_PORT = 5006;
var MAX_PROTOCOL_VERSION = 1;
var MAX_PIXELS = 140;
var UDP_PORT = 5005;
PixelVloedClient = {
/*Sets up a client
Arguments:
firstserver: (bool) False, select the first server immediately
debug: (bool) False
ip: (str) None
port: (int) None
width: (int) 640
height: (int) 480
Listens for servers if no ip is given
*/
discoverysock: null,
sock: null,
sleep: 100,
debug: true,
width: 640,
height: 480,
effect: null,
alpha: false,
init: function(firstserver, debug,
ip, port,
width, height,
effect, alpha){
if(debug){ this.debug = debug; }
if(effect){ this.effect = effect; }
if(alpha){ this.alpha = alpha; }
if (ip){
this.ipaddress = ip;
this.port = (port?port:UDP_PORT);
this.width = width;
this.height = height;
this.start();
} else {
this.DiscoverServers(firstserver)
}
},
start: function(){
this.sock = dgram.createSocket('udp4');
if (this.debug){
console.log('displaying on '+this.ipaddress+':'+this.port+', '+this.width+'*'+this.height+'px');
}
this.effect();
},
Sleep: function(duration){
// Sleeps the designated amount of time
sleep.usleep((duration?duration:this.sleep) * 1000);
},
SendPacket: function(message, delay){
/*Sends the message to the udp server
Arguments:
message: (str, 140)
sleep: (bool) True, should the client sleep for a while?
*/
this.sock.send(message, 0, message.length,
this.port, this.ipaddress,
this.effect.bind(this));
if (delay){
sleep.usleep(this.sleep);
}
},
DiscoverServers: function (){
//Discover servers that send out the pixelvloed preample
this.discoverysock = dgram.createSocket("udp4");
this.discoverysock.on("message", this.handleDiscoveryPacket.bind(this));
this.discoverysock.on('error', function (err) {
console.error(err);
process.exit(0);
});
this.discoverysock.bind(DISCOVER_PORT);
},
handleDiscoveryPacket: function (data, rinfo) {
data = String(data);
console.log("server got: " + typeof String(data) + " from " + rinfo.address + ":" + rinfo.port);
if (data.startsWith(PROTOCOL_PREAMBLE)){
var dataset = data.split(' ');
if (dataset[0].split(':')[1] <= MAX_PROTOCOL_VERSION){
this.ipaddress = dataset[1].split(':')[0];
this.port = parseInt(dataset[1].split(':')[1], 10);
this.width = parseInt(dataset[2].split('*')[0], 10);
this.height = parseInt(dataset[2].split('*')[1], 10);
this.discoverysock.close();
this.start();
}
}
}
};
function NewMessage(alpha){
// Creates a new message with the correct max size, rgb mode and version
var message = new Buffer((MAX_PIXELS*(alpha?8:7))+2);
message.fill(0);
//MaxSizeList(+2);
message[0] = SetRGBAMode(alpha);
message[1] = SetVersionBit(1);
return message;
}
function RGBPixel(message, offset, x, y, r, g, b, a){
// Generates the packed data for a pixel
message.writeUInt16LE(x, offset);
message.writeUInt16LE(y, offset+2);
message.writeUInt8(r, offset+4);
message.writeUInt8(g, offset+5);
message.writeUInt8(b, offset+6);
if (a){
message.writeUInt8(a, offset+7);
}
}
function SetRGBAMode(mode){
// Generate the rgb/rgba bit
return struct.Pack("<B", [mode]);
}
function SetVersionBit(protocol){
// Generate the Version bit
return struct.Pack("<B", [protocol]);
}
function RandomFill(width, height){
// Generates a random number of pixels with a random color
var msg = NewMessage();
for(var i=0; i<getRandomIntInclusive(10, MAX_PIXELS); i++){
RGBPixel(msg, (i*(this.alpha?8:7))+2,
getRandomIntInclusive(0, width),
getRandomIntInclusive(0, height),
getRandomIntInclusive(0, 255),
getRandomIntInclusive(0, 255),
getRandomIntInclusive(0, 255),
(this.alpha?getRandomIntInclusive(0, 255):null))
}
return msg;
}
// Create a new client instance
var client = PixelVloedClient;
// bind the effect
client.effect = function(err, bytes){
if (err) throw err;
var msg = RandomFill(client.width, client.height);
client.SendPacket(msg);
}
// Init the clients autodetection
client.init();
// helpers
function getRandomIntInclusive(min, max) {
return Math.floor(Math.random() * (max - min + 1)) + min;
}
// polyfills
if (!String.prototype.startsWith) {
String.prototype.startsWith = function(searchString, position){
position = position || 0;
return this.substr(position, searchString.length) === searchString;
};
}