This commit is contained in:
Hri7566 2022-01-13 00:18:06 -05:00
parent d29bd9dc85
commit 72c0e15614
28 changed files with 16711 additions and 16376 deletions

4
.gitignore vendored
View File

@ -1,3 +1,3 @@
.env
node_modules
.env
node_modules
.history

View File

@ -1 +1 @@
# booger
# booger

View File

@ -1 +1 @@
MANIFEST-000204
MANIFEST-000204

View File

@ -1,5 +1,5 @@
2021/08/06-00:35:25.097 6b0c Recovering log #203
2021/08/06-00:35:25.097 6b0c Level-0 table #205: started
2021/08/06-00:35:25.105 6b0c Level-0 table #205: 316 bytes OK
2021/08/06-00:35:25.121 6b0c Delete type=0 #203
2021/08/06-00:35:25.124 6b0c Delete type=3 #202
2021/08/06-00:35:25.097 6b0c Recovering log #203
2021/08/06-00:35:25.097 6b0c Level-0 table #205: started
2021/08/06-00:35:25.105 6b0c Level-0 table #205: 316 bytes OK
2021/08/06-00:35:25.121 6b0c Delete type=0 #203
2021/08/06-00:35:25.124 6b0c Delete type=3 #202

View File

@ -1,3 +1,3 @@
2021/08/06-00:34:35.908 5ec4 Recovering log #201
2021/08/06-00:34:35.923 5ec4 Delete type=0 #201
2021/08/06-00:34:35.925 5ec4 Delete type=3 #200
2021/08/06-00:34:35.908 5ec4 Recovering log #201
2021/08/06-00:34:35.923 5ec4 Delete type=0 #201
2021/08/06-00:34:35.925 5ec4 Delete type=3 #200

Binary file not shown.

Binary file not shown.

BIN
bot2022.db/000374.log Normal file

Binary file not shown.

BIN
bot2022.db/000375.ldb Normal file

Binary file not shown.

View File

@ -1 +1 @@
MANIFEST-000281
MANIFEST-000372

View File

@ -1,14 +1,11 @@
2022/01/12-18:47:05.981699 7f256d68d700 Recovering log #280
2022/01/12-18:47:05.981991 7f256d68d700 Level-0 table #282: started
2022/01/12-18:47:05.986039 7f256d68d700 Level-0 table #282: 1528 bytes OK
2022/01/12-18:47:05.988706 7f256d68d700 Delete type=0 #280
2022/01/12-18:47:05.988750 7f256d68d700 Delete type=3 #278
2022/01/12-18:47:05.992305 7f255f7fe700 Compacting 4@0 + 1@1 files
2022/01/12-18:47:06.002027 7f255f7fe700 Generated table #284@0: 66 keys, 4235 bytes
2022/01/12-18:47:06.002080 7f255f7fe700 Compacted 4@0 + 1@1 files => 4235 bytes
2022/01/12-18:47:06.004105 7f255f7fe700 compacted to: files[ 0 1 0 0 0 0 0 ]
2022/01/12-18:47:06.004445 7f255f7fe700 Delete type=2 #271
2022/01/12-18:47:06.004613 7f255f7fe700 Delete type=2 #279
2022/01/12-18:47:06.004705 7f255f7fe700 Delete type=2 #276
2022/01/12-18:47:06.004781 7f255f7fe700 Delete type=2 #282
2022/01/12-18:47:06.004842 7f255f7fe700 Delete type=2 #273
2022/01/12-17:42:12.099 7cc4 Recovering log #370
2022/01/12-17:42:12.103 7cc4 Level-0 table #373: started
2022/01/12-17:42:12.111 7cc4 Level-0 table #373: 67945 bytes OK
2022/01/12-17:42:12.115 7cc4 Delete type=0 #370
2022/01/12-17:42:12.116 7cc4 Delete type=3 #368
2022/01/12-19:28:57.060 2944 Compacting 1@0 + 1@1 files
2022/01/12-19:28:57.063 2944 Generated table #375@0: 57 keys, 3838 bytes
2022/01/12-19:28:57.063 2944 Compacted 1@0 + 1@1 files => 3838 bytes
2022/01/12-19:28:57.064 2944 compacted to: files[ 0 1 0 0 0 0 0 ]
2022/01/12-19:28:57.064 2944 Delete type=2 #371
2022/01/12-19:28:57.065 2944 Delete type=2 #373

View File

@ -1,5 +1,13 @@
2022/01/12-18:44:02.311542 7f2decce2700 Recovering log #277
2022/01/12-18:44:02.312469 7f2decce2700 Level-0 table #279: started
2022/01/12-18:44:02.319879 7f2decce2700 Level-0 table #279: 6762 bytes OK
2022/01/12-18:44:02.327618 7f2decce2700 Delete type=0 #277
2022/01/12-18:44:02.327833 7f2decce2700 Delete type=3 #275
2022/01/12-16:14:05.171 7c80 Recovering log #367
2022/01/12-16:14:05.172 7c80 Level-0 table #369: started
2022/01/12-16:14:05.173 7c80 Level-0 table #369: 2167 bytes OK
2022/01/12-16:14:05.178 7c80 Delete type=0 #367
2022/01/12-16:14:05.178 7c80 Delete type=3 #365
2022/01/12-16:21:34.033 2ff0 Compacting 3@0 + 1@1 files
2022/01/12-16:21:34.034 2ff0 Generated table #371@0: 49 keys, 3381 bytes
2022/01/12-16:21:34.034 2ff0 Compacted 3@0 + 1@1 files => 3381 bytes
2022/01/12-16:21:34.036 2ff0 compacted to: files[ 0 1 0 0 0 0 0 ]
2022/01/12-16:21:34.036 2ff0 Delete type=2 #361
2022/01/12-16:21:34.036 2ff0 Delete type=2 #363
2022/01/12-16:21:34.036 2ff0 Delete type=2 #366
2022/01/12-16:21:34.037 2ff0 Delete type=2 #369

Binary file not shown.

BIN
bot2022.db/MANIFEST-000372 Normal file

Binary file not shown.

400
index.js
View File

@ -1,200 +1,200 @@
require('dotenv').config();
globalThis.gBot = require('./src/Bot');
const level = require('level');
const MPPClient = require('./src/MPPClient');
globalThis.db = level("./bot2022.db");
let sendChat = MPPClient.sendChat;
db.getPokemon = function(id, cb) {
var key = "pokemon collection~"+id;
db.get(key, function(err, value) {
if(err || !value || value == "") {
cb([]);
return;
}
var result = [];
value = value.split("\xff");
for(var i = 0; i < value.length; i++) {
var v = value[i].trim();
if(v.length) result.push(v);
}
cb(result);
});
}
db.putPokemon = function(id, arr) {
var result = "";
for(var i = 0; i < arr.length; i++) {
var v = arr[i];
if(!v) continue;
v = v.trim();
if(v.length > 0) {
if(i) result += "\xff";
result += v;
}
}
var key = "pokemon collection~"+id;
if(result.length)
db.put(key, result);
else
db.del(key);
}
db.readArray = function(start, end, cb) {
var results = [];
db.createReadStream({
start: start,
end: end
})
.on("data", function(data) {
results.push(data);
})
.on("end", function() {
cb(results);
});
};
function listArray(arr) {
var result = "";
for(var i = 0; i < arr.length; i++) {
if(i && i !== arr.length - 1) result += ", ";
if(i && i === arr.length - 1) result += ", and ";
result += arr[i];
}
return result;
}
// tries to find the thing by text
// calls cb with undefined or entry
db.look = function(location, text, cb) {
text = text.toLowerCase().trim();
if(text == "") {
// "/look" with no search text
db.get("look."+location, function(err, value) {
var response = "";
if(err) response = "Well...";
else response = value;
var sel = "look."+location+".◍";
db.readArray(sel, sel+"\xff", function(results) {
var results = results.map(data=>data.key.substr(sel.length));
if(results.length) response += " There's "+listArray(results)+ ", about.";
sendChat(response);
});
});
} else {
var entry = undefined;
var sel = "look."+location+".";
db.createReadStream({
start: sel,
end: sel+"◍\xff"
})
.on("data", function(data) {
if(data.key.substr(sel.length).toLowerCase().indexOf(text) > -1) {
entry = data;
}
})
.on("end", function() {
cb(entry);
});
}
}
db.take = function(location, text, cb) {
text = text.toLowerCase().trim();
var sel = "look."+location+".◍";
var entry = undefined;
db.createReadStream({
start: sel,
end: sel+"\xff"
})
.on("data", function(data) {
if(data.key.substr(sel.length).toLowerCase().indexOf(text) > -1) {
entry = data;
}
})
.on("end", function() {
cb(entry);
});
}
db.getLocation = function(id, cb) {
var key = "location~"+id;
db.get(key, function(err, value) {
if(err || !value || value == "") {
return cb("outside");
}
return cb(value);
});
}
db.setLocation = function(id, location) {
if(!location || location === "") {
location = "outside";
}
db.put("location~"+id, location);
}
db.getFish = function(id, cb) {
var key = "fish sack~"+id;
db.get(key, function(err, value) {
if(err || !value || value == "") {
cb([]);
return;
}
var result = [];
value = value.split("\xff");
for(var i = 0; i < value.length; i++) {
var v = value[i].trim();
if(v.length) result.push(v);
}
cb(result);
});
}
db.putFish = function(id, arr) {
var result = "";
for(var i = 0; i < arr.length; i++) {
var v = arr[i];
if(!v) continue;
v = v.trim();
if(v.length > 0) {
if(i) result += "\xff";
result += v;
}
}
var key = "fish sack~"+id;
if(result.length)
db.put(key, result);
else
db.del(key);
}
db.appendFish = function(id, arr) {
db.getFish(id, function(myfish) {
myfish = myfish.concat(arr);
//console.log(id, myfish);
db.putFish(id, myfish);
});
}
db.getFruits = function(cb) {
var key = "kekklefruit tree";
db.get(key, function(err, value) {
if(err || !value || value == "") {
cb(0);
return;
}
cb(parseInt(value));
});
}
db.setFruits = function(num_fruits) {
var key = "kekklefruit tree";
db.put(key, num_fruits);
}
gBot.start(process.env.MPPCLONE_TOKEN);
require('dotenv').config();
globalThis.gBot = require('./src/Bot');
const level = require('level');
const MPPClient = require('./src/MPPClient');
globalThis.db = level("./bot2022.db");
let sendChat = MPPClient.sendChat;
db.getPokemon = function(id, cb) {
var key = "pokemon collection~"+id;
db.get(key, function(err, value) {
if(err || !value || value == "") {
cb([]);
return;
}
var result = [];
value = value.split("\xff");
for(var i = 0; i < value.length; i++) {
var v = value[i].trim();
if(v.length) result.push(v);
}
cb(result);
});
}
db.putPokemon = function(id, arr) {
var result = "";
for(var i = 0; i < arr.length; i++) {
var v = arr[i];
if(!v) continue;
v = v.trim();
if(v.length > 0) {
if(i) result += "\xff";
result += v;
}
}
var key = "pokemon collection~"+id;
if(result.length)
db.put(key, result);
else
db.del(key);
}
db.readArray = function(start, end, cb) {
var results = [];
db.createReadStream({
start: start,
end: end
})
.on("data", function(data) {
results.push(data);
})
.on("end", function() {
cb(results);
});
};
function listArray(arr) {
var result = "";
for(var i = 0; i < arr.length; i++) {
if(i && i !== arr.length - 1) result += ", ";
if(i && i === arr.length - 1) result += ", and ";
result += arr[i];
}
return result;
}
// tries to find the thing by text
// calls cb with undefined or entry
db.look = function(location, text, cb) {
text = text.toLowerCase().trim();
if(text == "") {
// "/look" with no search text
db.get("look."+location, function(err, value) {
var response = "";
if(err) response = "Well...";
else response = value;
var sel = "look."+location+".◍";
db.readArray(sel, sel+"\xff", function(results) {
var results = results.map(data=>data.key.substr(sel.length));
if(results.length) response += " There's "+listArray(results)+ ", about.";
sendChat(response);
});
});
} else {
var entry = undefined;
var sel = "look."+location+".";
db.createReadStream({
start: sel,
end: sel+"◍\xff"
})
.on("data", function(data) {
if(data.key.substr(sel.length).toLowerCase().indexOf(text) > -1) {
entry = data;
}
})
.on("end", function() {
cb(entry);
});
}
}
db.take = function(location, text, cb) {
text = text.toLowerCase().trim();
var sel = "look."+location+".◍";
var entry = undefined;
db.createReadStream({
start: sel,
end: sel+"\xff"
})
.on("data", function(data) {
if(data.key.substr(sel.length).toLowerCase().indexOf(text) > -1) {
entry = data;
}
})
.on("end", function() {
cb(entry);
});
}
db.getLocation = function(id, cb) {
var key = "location~"+id;
db.get(key, function(err, value) {
if(err || !value || value == "") {
return cb("outside");
}
return cb(value);
});
}
db.setLocation = function(id, location) {
if(!location || location === "") {
location = "outside";
}
db.put("location~"+id, location);
}
db.getFish = function(id, cb) {
var key = "fish sack~"+id;
db.get(key, function(err, value) {
if(err || !value || value == "") {
cb([]);
return;
}
var result = [];
value = value.split("\xff");
for(var i = 0; i < value.length; i++) {
var v = value[i].trim();
if(v.length) result.push(v);
}
cb(result);
});
}
db.putFish = function(id, arr) {
var result = "";
for(var i = 0; i < arr.length; i++) {
var v = arr[i];
if(!v) continue;
v = v.trim();
if(v.length > 0) {
if(i) result += "\xff";
result += v;
}
}
var key = "fish sack~"+id;
if(result.length)
db.put(key, result);
else
db.del(key);
}
db.appendFish = function(id, arr) {
db.getFish(id, function(myfish) {
myfish = myfish.concat(arr);
//console.log(id, myfish);
db.putFish(id, myfish);
});
}
db.getFruits = function(cb) {
var key = "kekklefruit tree";
db.get(key, function(err, value) {
if(err || !value || value == "") {
cb(0);
return;
}
cb(parseInt(value));
});
}
db.setFruits = function(num_fruits) {
var key = "kekklefruit tree";
db.put(key, num_fruits);
}
gBot.start(process.env.MPPCLONE_TOKEN);

1476
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -1,25 +1,25 @@
{
"name": "booger",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"repository": {
"type": "git",
"url": "git+https://gitlab.com/Hri7566/booger.git"
},
"keywords": [],
"author": "",
"license": "ISC",
"bugs": {
"url": "https://gitlab.com/Hri7566/booger/issues"
},
"homepage": "https://gitlab.com/Hri7566/booger#readme",
"dependencies": {
"discord.js": "^12.5.3",
"dotenv": "^9.0.1",
"level": "^6.0.1"
}
}
{
"name": "booger",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"repository": {
"type": "git",
"url": "git+https://gitlab.com/Hri7566/booger.git"
},
"keywords": [],
"author": "",
"license": "ISC",
"bugs": {
"url": "https://gitlab.com/Hri7566/booger/issues"
},
"homepage": "https://gitlab.com/Hri7566/booger#readme",
"dependencies": {
"discord.js": "^12.5.3",
"dotenv": "^9.0.1",
"level": "^6.0.1"
}
}

View File

@ -1,242 +1,245 @@
const { sendChat } = require('./MPPClient');
// const DiscordClient = require('./DiscordClient');
const MPPClient = require('./MPPClient');
const StaticEventEmitter = require('./StaticEventEmitter');
module.exports = class Bot extends StaticEventEmitter {
static start(token) {
MPPClient.start(token);
this.bindEventListeners();
this.commands = new Map();
this.admin = [
"2ffc3744fbc1bc6c6ef4a330",
"a41651bf8a46bafc5548dad6"
];
this.prefix = "/"; // never change this
this.loadCommands();
}
static bindEventListeners() {
this.on("chat.receive", msg => {
console.log(msg.p.name + ": " + msg.a);
let m = {
referer: msg.p,
};
this.runCommand(msg);
});
this.on("chat.send", msg => {
MPPClient.sendChat(msg);
});
}
static runCommand(msg) {
// let role;
// msg.member.guild.roles.cache.forEach(r => {
// if (r.name.toString() == msg.member.user.id.toString()) {
// role = r;
// }
// });
// msg.p = {
// name: msg.author.username,
// _id: msg.author.id,
// color: role.color,
// id: msg.author.id
// }
// msg.a = msg.content;
if(msg.a[0] == "" && msg.p.id !== client.participantId) {
msg.a[0] = "/";
}
function findParticipantByName(name) {
if(!name || name.trim() == "") return undefined;
for(var id in client.ppl) {
if(client.ppl.hasOwnProperty(id) && client.ppl[id].name === name) {
return client.ppl[id];
}
}
return undefined;
};
function findParticipantByNameCaseInsensitive(name) {
if(!name || name.trim() == "") return undefined;
var part = findParticipantByName(name);
if(!part) {
name_lc = name.toLowerCase();
MPPClient.client.ppl.forEach(p => {
if(p.name.toLowerCase() === name_lc) {
part = p;
}
});
}
return part;
};
function findParticipantByNameFuzzy(name) {
if(!name || name.trim() == "") return undefined;
name = name.toLowerCase();
var part = findParticipantByNameCaseInsensitive(name);
for(var id in MPPClient.client.ppl) {
if(client.ppl.hasOwnProperty(id) && client.ppl[id].name.toLowerCase().indexOf(name) === 0) {
part = client.ppl[id];
break;
}
}
for(var id in MPPClient.client.ppl) {
if(client.ppl.hasOwnProperty(id) && client.ppl[id].name.toLowerCase().indexOf(name) !== -1) {
part = MPPClient.client.ppl[id];
break;
}
}
return part;
};
if (msg.cmd.startsWith("give_")) {
// var amt = parseInt(msg.cmd.substr(5));
// console.log(msg.cmd.substr(5));
// if(amt > 0) {
// console.log('test');
// if(amt > 100 && msg.p.id !== client.participantId) {
// sendChat("Friend "+msg.p.name+": you can only give up to 100 at a time.");
// } else {
// var thief = msg.p;
// var victim = findParticipantByNameFuzzy(msg.args[0]);
// if(!victim) {
// sendChat("Friend " +thief.name+" missed");
// return;
// }
// if(victim._id == thief._id) {
// sendChat("Friendly friend " +thief.name+" fudged");
// return;
// }
// var target_fish = msg.argcat(1);
// db.getFish(thief._id, function(thief_fish) {
// db.getFish(victim._id, function(victim_fish) {
// if(victim_fish.length >= TOO_MANY_FISH) {
// sendChat("Friend " +victim.name+" is carrying too much.");
// return;
// }
// if(thief_fish.length > 0) {
// var arg = target_fish.trim().toLowerCase();
// var thefish = "items";
// for(var j = 0; j < amt; j++) {
// var idx = -1;
// for(var i = 0; i < thief_fish.length; i++) {
// if(arg == "" || thief_fish[i].toLowerCase().indexOf(arg) !== -1) {
// idx = i;
// break;
// }
// }
// if(idx == -1) {
// sendChat("Friend " +thief.name+": You don't have "+amt+" "+arg+".");
// return;
// }
// thefish = thief_fish[idx];
// thief_fish.splice(idx, 1);
// victim_fish.push(thefish);
// }
// sendChat("Our friend " +thief.name+" gave "+victim.name+" his/her e.g. ("+thefish+") x "+amt+".");
// db.putFish(thief._id, thief_fish);
// db.putFish(victim._id, victim_fish);
// } else {
// sendChat("Friend " +thief.name+": You don't have the fish to give.");
// }
// });
// });
// return;
// }
// }
return sendChat("You may not /give_, it misses every time.");
}
if (msg.cmd.startsWith("bestow_")) {
// var amt = parseInt(msg.cmd.substr(8));
// if(amt > 0) {
// if(amt > 100 && msg.p.id !== client.participantId) {
// sendChat("Friend "+msg.p.name+": you can only bestow up to 100 at a time.");
// } else {
// var thief = msg.p;
// var victim = client.ppl[msg.args[0]];
// if(!victim) {
// sendChat("Friend " +thief.name+" missed");
// return;
// }
// if(victim._id == thief._id) {
// sendChat("Friendly friend " +thief.name+" fudged");
// return;
// }
// var target_fish = msg.argcat(1);
// db.getFish(thief._id, function(thief_fish) {
// db.getFish(victim._id, function(victim_fish) {
// if(victim_fish.length >= TOO_MANY_FISH) {
// sendChat("Friend " +victim.name+" is carrying too much.");
// return;
// }
// if(thief_fish.length > 0) {
// var arg = target_fish.trim().toLowerCase();
// var thefish = "items";
// for(var j = 0; j < amt; j++) {
// var idx = -1;
// for(var i = 0; i < thief_fish.length; i++) {
// if(arg == "" || thief_fish[i].toLowerCase().indexOf(arg) !== -1) {
// idx = i;
// break;
// }
// }
// if(idx == -1) {
// sendChat("Friend " +thief.name+": You don't have "+amt+" "+arg+".");
// return;
// }
// thefish = thief_fish[idx];
// thief_fish.splice(idx, 1);
// victim_fish.push(thefish);
// }
// sendChat("Our friend " +thief.name+" bestowed "+victim.name+" his/her e.g. ("+thefish+") x "+amt+".");
// db.putFish(thief._id, thief_fish);
// db.putFish(victim._id, victim_fish);
// } else {
// sendChat("Friend " +thief.name+": You don't have the fish to bestow.");
// }
// });
// });
// return;
// }
// }
return sendChat("You may not /bestow_, it misses every time.");
}
this.commands.forEach(cmd => {
let usedCommand = false;
cmd.cmd.forEach(c => {
if (msg.cmd == c) {
usedCommand = true;
}
});
if (!usedCommand) return;
if (msg.rank == 'admin') {
cmd.func(msg, true);
} else {
cmd.func(msg, false);
}
});
}
static fixUsage(str) {
return str.split("&PREFIX").join(this.prefix);
}
static getRank(id) {
if (this.admin.indexOf(id) !== -1) {
return "admin";
} else {
return "none";
}
}
static async loadCommands() {
(require('./Commands'))(this);
}
}
const { sendChat } = require('./MPPClient');
// const DiscordClient = require('./DiscordClient');
const MPPClient = require('./MPPClient');
const StaticEventEmitter = require('./StaticEventEmitter');
module.exports = class Bot extends StaticEventEmitter {
static start(token) {
MPPClient.start(token);
this.bindEventListeners();
this.commands = new Map();
this.admin = [
"2ffc3744fbc1bc6c6ef4a330",
"a41651bf8a46bafc5548dad6"
];
this.prefix = "/"; // never change this
this.loadCommands();
}
static bindEventListeners() {
this.on("chat.receive", msg => {
console.log(msg.p.name + ": " + msg.a);
let m = {
referer: msg.p,
};
this.runCommand(msg);
});
this.on("chat.send", msg => {
MPPClient.sendChat(msg);
});
}
static runCommand(msg) {
// let role;
// msg.member.guild.roles.cache.forEach(r => {
// if (r.name.toString() == msg.member.user.id.toString()) {
// role = r;
// }
// });
// msg.p = {
// name: msg.author.username,
// _id: msg.author.id,
// color: role.color,
// id: msg.author.id
// }
// msg.a = msg.content;
if(msg.a[0] == "" && msg.p.id !== client.participantId) {
msg.a[0] = "/";
}
function findParticipantByName(name) {
if(!name || name.trim() == "") return undefined;
for(var id in client.ppl) {
if(client.ppl.hasOwnProperty(id) && client.ppl[id].name === name) {
return client.ppl[id];
}
}
return undefined;
};
function findParticipantByNameCaseInsensitive(name) {
if(!name || name.trim() == "") return undefined;
var part = findParticipantByName(name);
if(!part) {
name_lc = name.toLowerCase();
MPPClient.client.ppl.forEach(p => {
if(p.name.toLowerCase() === name_lc) {
part = p;
}
});
}
return part;
};
function findParticipantByNameFuzzy(name) {
if(!name || name.trim() == "") return undefined;
name = name.toLowerCase();
var part = findParticipantByNameCaseInsensitive(name);
for(var id in MPPClient.client.ppl) {
if(client.ppl.hasOwnProperty(id) && client.ppl[id].name.toLowerCase().indexOf(name) === 0) {
part = client.ppl[id];
break;
}
}
for(var id in MPPClient.client.ppl) {
if(client.ppl.hasOwnProperty(id) && client.ppl[id].name.toLowerCase().indexOf(name) !== -1) {
part = MPPClient.client.ppl[id];
break;
}
}
return part;
};
if (msg.cmd.startsWith("give_")) {
// var amt = parseInt(msg.cmd.substr(5));
// console.log(msg.cmd.substr(5));
// if(amt > 0) {
// console.log('test');
// if(amt > 100 && msg.p.id !== client.participantId) {
// sendChat("Friend "+msg.p.name+": you can only give up to 100 at a time.");
// } else {
// var thief = msg.p;
// var victim = findParticipantByNameFuzzy(msg.args[0]);
// if(!victim) {
// sendChat("Friend " +thief.name+" missed");
// return;
// }
// if(victim._id == thief._id) {
// sendChat("Friendly friend " +thief.name+" fudged");
// return;
// }
// var target_fish = msg.argcat(1);
// db.getFish(thief._id, function(thief_fish) {
// db.getFish(victim._id, function(victim_fish) {
// if(victim_fish.length >= TOO_MANY_FISH) {
// sendChat("Friend " +victim.name+" is carrying too much.");
// return;
// }
// if(thief_fish.length > 0) {
// var arg = target_fish.trim().toLowerCase();
// var thefish = "items";
// for(var j = 0; j < amt; j++) {
// var idx = -1;
// for(var i = 0; i < thief_fish.length; i++) {
// if(arg == "" || thief_fish[i].toLowerCase().indexOf(arg) !== -1) {
// idx = i;
// break;
// }
// }
// if(idx == -1) {
// sendChat("Friend " +thief.name+": You don't have "+amt+" "+arg+".");
// return;
// }
// thefish = thief_fish[idx];
// thief_fish.splice(idx, 1);
// victim_fish.push(thefish);
// }
// sendChat("Our friend " +thief.name+" gave "+victim.name+" his/her e.g. ("+thefish+") x "+amt+".");
// db.putFish(thief._id, thief_fish);
// db.putFish(victim._id, victim_fish);
// } else {
// sendChat("Friend " +thief.name+": You don't have the fish to give.");
// }
// });
// });
// return;
// }
// }
return sendChat("You may not /give_, it misses every time.");
}
if (msg.cmd.startsWith("bestow_")) {
// var amt = parseInt(msg.cmd.substr(8));
// if(amt > 0) {
// if(amt > 100 && msg.p.id !== client.participantId) {
// sendChat("Friend "+msg.p.name+": you can only bestow up to 100 at a time.");
// } else {
// var thief = msg.p;
// var victim = client.ppl[msg.args[0]];
// if(!victim) {
// sendChat("Friend " +thief.name+" missed");
// return;
// }
// if(victim._id == thief._id) {
// sendChat("Friendly friend " +thief.name+" fudged");
// return;
// }
// var target_fish = msg.argcat(1);
// db.getFish(thief._id, function(thief_fish) {
// db.getFish(victim._id, function(victim_fish) {
// if(victim_fish.length >= TOO_MANY_FISH) {
// sendChat("Friend " +victim.name+" is carrying too much.");
// return;
// }
// if(thief_fish.length > 0) {
// var arg = target_fish.trim().toLowerCase();
// var thefish = "items";
// for(var j = 0; j < amt; j++) {
// var idx = -1;
// for(var i = 0; i < thief_fish.length; i++) {
// if(arg == "" || thief_fish[i].toLowerCase().indexOf(arg) !== -1) {
// idx = i;
// break;
// }
// }
// if(idx == -1) {
// sendChat("Friend " +thief.name+": You don't have "+amt+" "+arg+".");
// return;
// }
// thefish = thief_fish[idx];
// thief_fish.splice(idx, 1);
// victim_fish.push(thefish);
// }
// sendChat("Our friend " +thief.name+" bestowed "+victim.name+" his/her e.g. ("+thefish+") x "+amt+".");
// db.putFish(thief._id, thief_fish);
// db.putFish(victim._id, victim_fish);
// } else {
// sendChat("Friend " +thief.name+": You don't have the fish to bestow.");
// }
// });
// });
// return;
// }
// }
return sendChat("You may not /bestow_, it misses every time.");
}
if (msg.a == '/get fruit') {
msg.cmd = 'get fruit'
}
this.commands.forEach(cmd => {
let usedCommand = false;
cmd.cmd.forEach(c => {
if (msg.cmd == c) {
usedCommand = true;
}
});
if (!usedCommand) return;
if (msg.rank == 'admin') {
cmd.func(msg, true);
} else {
cmd.func(msg, false);
}
});
}
static fixUsage(str) {
return str.split("&PREFIX").join(this.prefix);
}
static getRank(id) {
if (this.admin.indexOf(id) !== -1) {
return "admin";
} else {
return "none";
}
}
static async loadCommands() {
(require('./Commands'))(this);
}
}

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

View File

@ -1,73 +1,73 @@
const Discord = require('discord.js');
module.exports = class DiscordClient {
static client = new Discord.Client();
static start(token) {
this.client.login(token);
this.bindEventListeners();
}
static bindEventListeners() {
this.client.on('ready', () => {
process.stdout.write("\n********************************START********************************\n");
});
this.client.on('messageUpdate', msg => {
if (msg.system) return;
if (msg.author.bot) return;
this.handleMessage(msg);
});
this.client.on('message', msg => {
if (msg.system) return;
if (msg.author.bot) return;
this.handleMessage(msg);
});
this.client.on('guildMemberAdd', async guildMember => {
let role;
guildMember.guild.roles.cache.forEach(r => {
if (r.name.toString() == guildMember.user.id.toString()) {
role = r;
}
});
if (typeof role !== 'undefined') console.log('found role: ' + role.name);
if (!role) console.log('creating role');
if (!role) role = await guildMember.guild.roles.create({
data: {
name: guildMember.user.id,
color: Math.floor(Math.random()*16777215).toString(16)
},
reason: guildMember.user.id
});
if (role) guildMember.roles.add(role);
});
}
static handleMessage(msg) {
msg.args = msg.content.split(' ');
msg.cmd = msg.content.startsWith(gBot.prefix) ? msg.args[0].substring(gBot.prefix.length).trim() : "";
msg.args = msg.args.slice(1);
msg.argcat = function(start, end) {
var parts = msg.args.slice(start || 0, end || undefined);
var result = "";
for(var i = 0; i < parts.length; i++) {
result += parts[i];
if(i + 1 < parts.length) {
result += " ";
}
}
return result;
};
msg.rank = gBot.getRank(msg.author.id);
gBot.emit('chat.receive', msg);
}
static sendChat(str) {
DiscordClient.client.channels.cache.get('841331769658703954').send(str);
}
}
const Discord = require('discord.js');
module.exports = class DiscordClient {
static client = new Discord.Client();
static start(token) {
this.client.login(token);
this.bindEventListeners();
}
static bindEventListeners() {
this.client.on('ready', () => {
process.stdout.write("\n********************************START********************************\n");
});
this.client.on('messageUpdate', msg => {
if (msg.system) return;
if (msg.author.bot) return;
this.handleMessage(msg);
});
this.client.on('message', msg => {
if (msg.system) return;
if (msg.author.bot) return;
this.handleMessage(msg);
});
this.client.on('guildMemberAdd', async guildMember => {
let role;
guildMember.guild.roles.cache.forEach(r => {
if (r.name.toString() == guildMember.user.id.toString()) {
role = r;
}
});
if (typeof role !== 'undefined') console.log('found role: ' + role.name);
if (!role) console.log('creating role');
if (!role) role = await guildMember.guild.roles.create({
data: {
name: guildMember.user.id,
color: Math.floor(Math.random()*16777215).toString(16)
},
reason: guildMember.user.id
});
if (role) guildMember.roles.add(role);
});
}
static handleMessage(msg) {
msg.args = msg.content.split(' ');
msg.cmd = msg.content.startsWith(gBot.prefix) ? msg.args[0].substring(gBot.prefix.length).trim() : "";
msg.args = msg.args.slice(1);
msg.argcat = function(start, end) {
var parts = msg.args.slice(start || 0, end || undefined);
var result = "";
for(var i = 0; i < parts.length; i++) {
result += parts[i];
if(i + 1 < parts.length) {
result += " ";
}
}
return result;
};
msg.rank = gBot.getRank(msg.author.id);
gBot.emit('chat.receive', msg);
}
static sendChat(str) {
DiscordClient.client.channels.cache.get('841331769658703954').send(str);
}
}

View File

@ -1,79 +1,79 @@
// const Discord = require('discord.js');
const Client = require('./mppt-client.js');
module.exports = class MPPClient {
static start(token) {
this.client = new Client('wss://mppclone.com:8443', token);
this.client.start();
this.client.setChannel('✧𝓓𝓔𝓥 𝓡𝓸𝓸𝓶✧');
this.bindEventListeners();
}
static bindEventListeners() {
this.client.on('hi', () => {
process.stdout.write("\n********************************START********************************\n");
});
// this.client.on('messageUpdate', msg => {
// if (msg.system) return;
// if (msg.author.bot) return;
// this.handleMessage(msg);
// });
this.client.on('a', msg => {
// if (msg.system) return;
// if (msg.author.bot) return;
// if (msg.p.tag)
this.handleMessage(msg);
});
// this.client.on('guildMemberAdd', async guildMember => {
// let role;
// guildMember.guild.roles.cache.forEach(r => {
// if (r.name.toString() == guildMember.user.id.toString()) {
// role = r;
// }
// });
// if (typeof role !== 'undefined') console.log('found role: ' + role.name);
// if (!role) console.log('creating role');
// if (!role) role = await guildMember.guild.roles.create({
// data: {
// name: guildMember.user.id,
// color: Math.floor(Math.random()*16777215).toString(16)
// },
// reason: guildMember.user.id
// });
// if (role) guildMember.roles.add(role);
// });
}
static handleMessage(msg) {
msg.args = msg.a.split(' ');
msg.cmd = msg.a.startsWith(gBot.prefix) ? msg.args[0].substring(gBot.prefix.length).trim() : "";
msg.args = msg.args.slice(1);
msg.argcat = function(start, end) {
var parts = msg.args.slice(start || 0, end || undefined);
var result = "";
for(var i = 0; i < parts.length; i++) {
result += parts[i];
if(i + 1 < parts.length) {
result += " ";
}
}
return result;
};
msg.rank = gBot.getRank(msg.p._id);
gBot.emit('chat.receive', msg);
}
static sendChat(str, skip = false) {
// DiscordClient.client.channels.cache.get('841331769658703954').send(str);
MPPClient.client.sendArray([{
m:'a',
message: skip == true ? str : `\u034f${str}`
}]);
}
}
// const Discord = require('discord.js');
const Client = require('./mppt-client.js');
module.exports = class MPPClient {
static start(token) {
this.client = new Client('wss://mppclone.com:8443', token);
this.client.start();
this.client.setChannel('✧𝓓𝓔𝓥 𝓡𝓸𝓸𝓶✧');
this.bindEventListeners();
}
static bindEventListeners() {
this.client.on('hi', () => {
process.stdout.write("\n********************************START********************************\n");
});
// this.client.on('messageUpdate', msg => {
// if (msg.system) return;
// if (msg.author.bot) return;
// this.handleMessage(msg);
// });
this.client.on('a', msg => {
// if (msg.system) return;
// if (msg.author.bot) return;
// if (msg.p.tag)
this.handleMessage(msg);
});
// this.client.on('guildMemberAdd', async guildMember => {
// let role;
// guildMember.guild.roles.cache.forEach(r => {
// if (r.name.toString() == guildMember.user.id.toString()) {
// role = r;
// }
// });
// if (typeof role !== 'undefined') console.log('found role: ' + role.name);
// if (!role) console.log('creating role');
// if (!role) role = await guildMember.guild.roles.create({
// data: {
// name: guildMember.user.id,
// color: Math.floor(Math.random()*16777215).toString(16)
// },
// reason: guildMember.user.id
// });
// if (role) guildMember.roles.add(role);
// });
}
static handleMessage(msg) {
msg.args = msg.a.split(' ');
msg.cmd = msg.a.startsWith(gBot.prefix) ? msg.args[0].substring(gBot.prefix.length).trim() : "";
msg.args = msg.args.slice(1);
msg.argcat = function(start, end) {
var parts = msg.args.slice(start || 0, end || undefined);
var result = "";
for(var i = 0; i < parts.length; i++) {
result += parts[i];
if(i + 1 < parts.length) {
result += " ";
}
}
return result;
};
msg.rank = gBot.getRank(msg.p._id);
gBot.emit('chat.receive', msg);
}
static sendChat(str, skip = false) {
// DiscordClient.client.channels.cache.get('841331769658703954').send(str);
MPPClient.client.sendArray([{
m:'a',
message: skip == true ? str : `\u034f${str}`
}]);
}
}

View File

@ -1,69 +1,69 @@
var RateLimit = function(interval_ms) {
this._interval_ms = interval_ms || 0; // (0 means no limit)
this._after = 0;
};
RateLimit.prototype.attempt = function(time) {
var time = time || Date.now();
if(time < this._after) return false;
this._after = time + this._interval_ms;
return true;
};
RateLimit.prototype.setInterval = function(interval_ms) {
this._after += interval_ms - this._interval_ms;
this._interval_ms = interval_ms;
};
var RateLimitChain = function(num, interval_ms) {
this.setNumAndInterval(num, interval_ms);
};
RateLimitChain.prototype.attempt = function(time) {
var time = time || Date.now();
for(var i = 0; i < this._chain.length; i++) {
if(this._chain[i].attempt(time)) return true;
}
return false;
};
RateLimitChain.prototype.setNumAndInterval = function(num, interval_ms) {
this._chain = [];
for(var i = 0; i < num; i++) {
this._chain.push(new RateLimit(interval_ms));
}
};
var DataRateLimit = function(limit, interval_ms) {
this._limit = limit;
this._interval_ms = interval_ms || 0; // 0: per-attempt
this._after = 0;
this._size = 0;
};
DataRateLimit.prototype.attempt = function(size, time) {
var time = time || Date.now();
if(time >= this._after) {
this._size = 0;
this._after = time + this._interval_ms;
}
if(this._size + size <= this._limit) {
this._size += size;
return true;
} else {
return false;
}
};
var exports = typeof module !== "undefined" ? module.exports : this;
exports.RateLimit = RateLimit;
exports.RateLimitChain = RateLimitChain;
var RateLimit = function(interval_ms) {
this._interval_ms = interval_ms || 0; // (0 means no limit)
this._after = 0;
};
RateLimit.prototype.attempt = function(time) {
var time = time || Date.now();
if(time < this._after) return false;
this._after = time + this._interval_ms;
return true;
};
RateLimit.prototype.setInterval = function(interval_ms) {
this._after += interval_ms - this._interval_ms;
this._interval_ms = interval_ms;
};
var RateLimitChain = function(num, interval_ms) {
this.setNumAndInterval(num, interval_ms);
};
RateLimitChain.prototype.attempt = function(time) {
var time = time || Date.now();
for(var i = 0; i < this._chain.length; i++) {
if(this._chain[i].attempt(time)) return true;
}
return false;
};
RateLimitChain.prototype.setNumAndInterval = function(num, interval_ms) {
this._chain = [];
for(var i = 0; i < num; i++) {
this._chain.push(new RateLimit(interval_ms));
}
};
var DataRateLimit = function(limit, interval_ms) {
this._limit = limit;
this._interval_ms = interval_ms || 0; // 0: per-attempt
this._after = 0;
this._size = 0;
};
DataRateLimit.prototype.attempt = function(size, time) {
var time = time || Date.now();
if(time >= this._after) {
this._size = 0;
this._after = time + this._interval_ms;
}
if(this._size + size <= this._limit) {
this._size += size;
return true;
} else {
return false;
}
};
var exports = typeof module !== "undefined" ? module.exports : this;
exports.RateLimit = RateLimit;
exports.RateLimitChain = RateLimitChain;
exports.DataRateLimit = DataRateLimit;

View File

@ -1,16 +1,16 @@
module.exports = class StaticEventEmitter {
static _events = {};
static on(event, cb) {
if (typeof this._events[event] == 'undefined') this._events[event] = [];
this._events[event].push(cb);
}
static emit(evtn) {
if(!this._events.hasOwnProperty(evtn)) return;
var fns = this._events[evtn].slice(0);
if(fns.length < 1) return;
var args = Array.prototype.slice.call(arguments, 1);
for(var i = 0; i < fns.length; i++) fns[i].apply(this, args);
}
module.exports = class StaticEventEmitter {
static _events = {};
static on(event, cb) {
if (typeof this._events[event] == 'undefined') this._events[event] = [];
this._events[event].push(cb);
}
static emit(evtn) {
if(!this._events.hasOwnProperty(evtn)) return;
var fns = this._events[evtn].slice(0);
if(fns.length < 1) return;
var args = Array.prototype.slice.call(arguments, 1);
for(var i = 0; i < fns.length; i++) fns[i].apply(this, args);
}
}

View File

@ -1,315 +1,315 @@
if(typeof module !== "undefined") {
module.exports = Client;
WebSocket = require("ws");
EventEmitter = require("events").EventEmitter;
} else {
this.Client = Client;
}
function mixin(obj1, obj2) {
for(var i in obj2) {
if(obj2.hasOwnProperty(i)) {
obj1[i] = obj2[i];
}
}
};
function Client(uri, token) {
EventEmitter.call(this);
this.uri = uri;
this.ws = undefined;
this.serverTimeOffset = 0;
this.user = undefined;
this.participantId = undefined;
this.channel = undefined;
this.ppl = {};
this.connectionTime = undefined;
this.connectionAttempts = 0;
this.desiredChannelId = undefined;
this.desiredChannelSettings = undefined;
this.pingInterval = undefined;
this.canConnect = false;
this.noteBuffer = [];
this.noteBufferTime = 0;
this.noteFlushInterval = undefined;
this.token = token;
this.bindEventListeners();
this.emit("status", "(Offline mode)");
};
mixin(Client.prototype, EventEmitter.prototype);
Client.prototype.constructor = Client;
Client.prototype.isSupported = function() {
return typeof WebSocket === "function";
};
Client.prototype.isConnected = function() {
return this.isSupported() && this.ws && this.ws.readyState === WebSocket.OPEN;
};
Client.prototype.isConnecting = function() {
return this.isSupported() && this.ws && this.ws.readyState === WebSocket.CONNECTING;
};
Client.prototype.start = function() {
this.canConnect = true;
this.connect();
};
Client.prototype.stop = function() {
this.canConnect = false;
this.ws.close();
};
Client.prototype.connect = function() {
if(!this.canConnect || !this.isSupported() || this.isConnected() || this.isConnecting())
return;
this.emit("status", "Connecting...");
this.ws = new WebSocket(this.uri);
this.ws.binaryType = "arraybuffer";
var self = this;
this.ws.addEventListener("close", function(evt) {
self.user = undefined;
self.participantId = undefined;
self.channel = undefined;
self.setParticipants([]);
clearInterval(self.pingInterval);
clearInterval(self.noteFlushInterval);
self.emit("disconnect");
self.emit("status", "Offline mode");
// reconnect!
if(self.connectionTime) {
self.connectionTime = undefined;
self.connectionAttempts = 0;
} else {
++self.connectionAttempts;
}
var ms_lut = [50, 2950, 7000, 10000];
var idx = self.connectionAttempts;
if(idx >= ms_lut.length) idx = ms_lut.length - 1;
var ms = ms_lut[idx];
setTimeout(self.connect.bind(self), ms);
});
this.ws.addEventListener("open", function(evt) {
self.connectionTime = Date.now();
self.sendArray([{m: "hi", token: self.token}]);
self.pingInterval = setInterval(function() {
self.sendArray([{m: "t", e: Date.now()}]);
}, 20000);
//self.sendArray([{m: "t", e: Date.now()}]);
self.noteBuffer = [];
self.noteBufferTime = 0;
self.noteFlushInterval = setInterval(function() {
if(self.noteBufferTime && self.noteBuffer.length > 0) {
self.sendArray([{m: "n", t: self.noteBufferTime + self.serverTimeOffset, n: self.noteBuffer}]);
self.noteBufferTime = 0;
self.noteBuffer = [];
}
}, 200);
self.emit("connect");
self.emit("status", "Joining channel...");
});
this.ws.addEventListener("message", function(evt) {
if(typeof evt.data !== 'string') return;
var transmission = JSON.parse(evt.data);
for(var i = 0; i < transmission.length; i++) {
var msg = transmission[i];
self.emit(msg.m, msg);
}
});
};
Client.prototype.bindEventListeners = function() {
var self = this;
this.on("hi", function(msg) {
self.user = msg.u;
self.receiveServerTime(msg.t, msg.e || undefined);
if(self.desiredChannelId) {
self.setChannel();
}
});
this.on("t", function(msg) {
self.receiveServerTime(msg.t, msg.e || undefined);
});
this.on("ch", function(msg) {
self.desiredChannelId = msg.ch._id;
self.channel = msg.ch;
if(msg.p) self.participantId = msg.p;
self.setParticipants(msg.ppl);
});
this.on("p", function(msg) {
self.participantUpdate(msg);
self.emit("participant update", self.findParticipantById(msg.id));
});
this.on("m", function(msg) {
if(self.ppl.hasOwnProperty(msg.id)) {
self.participantUpdate(msg);
}
});
this.on("bye", function(msg) {
self.removeParticipant(msg.p);
});
};
Client.prototype.send = function(raw) {
if(this.isConnected()) this.ws.send(raw);
};
Client.prototype.sendArray = function(arr) {
this.send(JSON.stringify(arr));
};
Client.prototype.setChannel = function(id, set) {
this.desiredChannelId = id || this.desiredChannelId || "lobby";
this.desiredChannelSettings = set || this.desiredChannelSettings || undefined;
this.sendArray([{m: "ch", _id: this.desiredChannelId, set: this.desiredChannelSettings}]);
};
Client.prototype.offlineChannelSettings = {
lobby: true,
visible: false,
chat: false,
crownsolo: false,
color:"#ecfaed"
};
Client.prototype.getChannelSetting = function(key) {
if(!this.isConnected() || !this.channel || !this.channel.settings) {
return this.offlineChannelSettings[key];
}
return this.channel.settings[key];
};
Client.prototype.offlineParticipant = {
name: "",
color: "#777"
};
Client.prototype.getOwnParticipant = function() {
return this.findParticipantById(this.participantId);
};
Client.prototype.setParticipants = function(ppl) {
// remove participants who left
for(var id in this.ppl) {
if(!this.ppl.hasOwnProperty(id)) continue;
var found = false;
for(var j = 0; j < ppl.length; j++) {
if(ppl[j].id === id) {
found = true;
break;
}
}
if(!found) {
this.removeParticipant(id);
}
}
// update all
for(var i = 0; i < ppl.length; i++) {
this.participantUpdate(ppl[i]);
}
};
Client.prototype.countParticipants = function() {
var count = 0;
for(var i in this.ppl) {
if(this.ppl.hasOwnProperty(i)) ++count;
}
return count;
};
Client.prototype.participantUpdate = function(update) {
var part = this.ppl[update.id] || null;
if(part === null) {
part = update;
this.ppl[part.id] = part;
this.emit("participant added", part);
this.emit("count", this.countParticipants());
} else {
if(update.x) part.x = update.x;
if(update.y) part.y = update.y;
if(update.color) part.color = update.color;
if(update.name) part.name = update.name;
}
};
Client.prototype.removeParticipant = function(id) {
if(this.ppl.hasOwnProperty(id)) {
var part = this.ppl[id];
delete this.ppl[id];
this.emit("participant removed", part);
this.emit("count", this.countParticipants());
}
};
Client.prototype.findParticipantById = function(id) {
return this.ppl[id] || this.offlineParticipant;
};
Client.prototype.isOwner = function() {
return this.channel && this.channel.crown && this.channel.crown.participantId === this.participantId;
};
Client.prototype.preventsPlaying = function() {
return this.isConnected() && !this.isOwner() && this.getChannelSetting("crownsolo") === true;
};
Client.prototype.receiveServerTime = function(time, echo) {
var self = this;
var now = Date.now();
var target = time - now;
//console.log("Target serverTimeOffset: " + target);
var duration = 1000;
var step = 0;
var steps = 50;
var step_ms = duration / steps;
var difference = target - this.serverTimeOffset;
var inc = difference / steps;
var iv;
iv = setInterval(function() {
self.serverTimeOffset += inc;
if(++step >= steps) {
clearInterval(iv);
//console.log("serverTimeOffset reached: " + self.serverTimeOffset);
self.serverTimeOffset=target;
}
}, step_ms);
// smoothen
//this.serverTimeOffset = time - now; // mostly time zone offset ... also the lags so todo smoothen this
// not smooth:
//if(echo) this.serverTimeOffset += echo - now; // mostly round trip time offset
};
Client.prototype.startNote = function(note, vel) {
if(this.isConnected()) {
var vel = typeof vel === "undefined" ? undefined : +vel.toFixed(3);
if(!this.noteBufferTime) {
this.noteBufferTime = Date.now();
this.noteBuffer.push({n: note, v: vel});
} else {
this.noteBuffer.push({d: Date.now() - this.noteBufferTime, n: note, v: vel});
}
}
};
Client.prototype.stopNote = function(note) {
if(this.isConnected()) {
if(!this.noteBufferTime) {
this.noteBufferTime = Date.now();
this.noteBuffer.push({n: note, s: 1});
} else {
this.noteBuffer.push({d: Date.now() - this.noteBufferTime, n: note, s: 1});
}
}
if(typeof module !== "undefined") {
module.exports = Client;
WebSocket = require("ws");
EventEmitter = require("events").EventEmitter;
} else {
this.Client = Client;
}
function mixin(obj1, obj2) {
for(var i in obj2) {
if(obj2.hasOwnProperty(i)) {
obj1[i] = obj2[i];
}
}
};
function Client(uri, token) {
EventEmitter.call(this);
this.uri = uri;
this.ws = undefined;
this.serverTimeOffset = 0;
this.user = undefined;
this.participantId = undefined;
this.channel = undefined;
this.ppl = {};
this.connectionTime = undefined;
this.connectionAttempts = 0;
this.desiredChannelId = undefined;
this.desiredChannelSettings = undefined;
this.pingInterval = undefined;
this.canConnect = false;
this.noteBuffer = [];
this.noteBufferTime = 0;
this.noteFlushInterval = undefined;
this.token = token;
this.bindEventListeners();
this.emit("status", "(Offline mode)");
};
mixin(Client.prototype, EventEmitter.prototype);
Client.prototype.constructor = Client;
Client.prototype.isSupported = function() {
return typeof WebSocket === "function";
};
Client.prototype.isConnected = function() {
return this.isSupported() && this.ws && this.ws.readyState === WebSocket.OPEN;
};
Client.prototype.isConnecting = function() {
return this.isSupported() && this.ws && this.ws.readyState === WebSocket.CONNECTING;
};
Client.prototype.start = function() {
this.canConnect = true;
this.connect();
};
Client.prototype.stop = function() {
this.canConnect = false;
this.ws.close();
};
Client.prototype.connect = function() {
if(!this.canConnect || !this.isSupported() || this.isConnected() || this.isConnecting())
return;
this.emit("status", "Connecting...");
this.ws = new WebSocket(this.uri);
this.ws.binaryType = "arraybuffer";
var self = this;
this.ws.addEventListener("close", function(evt) {
self.user = undefined;
self.participantId = undefined;
self.channel = undefined;
self.setParticipants([]);
clearInterval(self.pingInterval);
clearInterval(self.noteFlushInterval);
self.emit("disconnect");
self.emit("status", "Offline mode");
// reconnect!
if(self.connectionTime) {
self.connectionTime = undefined;
self.connectionAttempts = 0;
} else {
++self.connectionAttempts;
}
var ms_lut = [50, 2950, 7000, 10000];
var idx = self.connectionAttempts;
if(idx >= ms_lut.length) idx = ms_lut.length - 1;
var ms = ms_lut[idx];
setTimeout(self.connect.bind(self), ms);
});
this.ws.addEventListener("open", function(evt) {
self.connectionTime = Date.now();
self.sendArray([{m: "hi", token: self.token}]);
self.pingInterval = setInterval(function() {
self.sendArray([{m: "t", e: Date.now()}]);
}, 20000);
//self.sendArray([{m: "t", e: Date.now()}]);
self.noteBuffer = [];
self.noteBufferTime = 0;
self.noteFlushInterval = setInterval(function() {
if(self.noteBufferTime && self.noteBuffer.length > 0) {
self.sendArray([{m: "n", t: self.noteBufferTime + self.serverTimeOffset, n: self.noteBuffer}]);
self.noteBufferTime = 0;
self.noteBuffer = [];
}
}, 200);
self.emit("connect");
self.emit("status", "Joining channel...");
});
this.ws.addEventListener("message", function(evt) {
if(typeof evt.data !== 'string') return;
var transmission = JSON.parse(evt.data);
for(var i = 0; i < transmission.length; i++) {
var msg = transmission[i];
self.emit(msg.m, msg);
}
});
};
Client.prototype.bindEventListeners = function() {
var self = this;
this.on("hi", function(msg) {
self.user = msg.u;
self.receiveServerTime(msg.t, msg.e || undefined);
if(self.desiredChannelId) {
self.setChannel();
}
});
this.on("t", function(msg) {
self.receiveServerTime(msg.t, msg.e || undefined);
});
this.on("ch", function(msg) {
self.desiredChannelId = msg.ch._id;
self.channel = msg.ch;
if(msg.p) self.participantId = msg.p;
self.setParticipants(msg.ppl);
});
this.on("p", function(msg) {
self.participantUpdate(msg);
self.emit("participant update", self.findParticipantById(msg.id));
});
this.on("m", function(msg) {
if(self.ppl.hasOwnProperty(msg.id)) {
self.participantUpdate(msg);
}
});
this.on("bye", function(msg) {
self.removeParticipant(msg.p);
});
};
Client.prototype.send = function(raw) {
if(this.isConnected()) this.ws.send(raw);
};
Client.prototype.sendArray = function(arr) {
this.send(JSON.stringify(arr));
};
Client.prototype.setChannel = function(id, set) {
this.desiredChannelId = id || this.desiredChannelId || "lobby";
this.desiredChannelSettings = set || this.desiredChannelSettings || undefined;
this.sendArray([{m: "ch", _id: this.desiredChannelId, set: this.desiredChannelSettings}]);
};
Client.prototype.offlineChannelSettings = {
lobby: true,
visible: false,
chat: false,
crownsolo: false,
color:"#ecfaed"
};
Client.prototype.getChannelSetting = function(key) {
if(!this.isConnected() || !this.channel || !this.channel.settings) {
return this.offlineChannelSettings[key];
}
return this.channel.settings[key];
};
Client.prototype.offlineParticipant = {
name: "",
color: "#777"
};
Client.prototype.getOwnParticipant = function() {
return this.findParticipantById(this.participantId);
};
Client.prototype.setParticipants = function(ppl) {
// remove participants who left
for(var id in this.ppl) {
if(!this.ppl.hasOwnProperty(id)) continue;
var found = false;
for(var j = 0; j < ppl.length; j++) {
if(ppl[j].id === id) {
found = true;
break;
}
}
if(!found) {
this.removeParticipant(id);
}
}
// update all
for(var i = 0; i < ppl.length; i++) {
this.participantUpdate(ppl[i]);
}
};
Client.prototype.countParticipants = function() {
var count = 0;
for(var i in this.ppl) {
if(this.ppl.hasOwnProperty(i)) ++count;
}
return count;
};
Client.prototype.participantUpdate = function(update) {
var part = this.ppl[update.id] || null;
if(part === null) {
part = update;
this.ppl[part.id] = part;
this.emit("participant added", part);
this.emit("count", this.countParticipants());
} else {
if(update.x) part.x = update.x;
if(update.y) part.y = update.y;
if(update.color) part.color = update.color;
if(update.name) part.name = update.name;
}
};
Client.prototype.removeParticipant = function(id) {
if(this.ppl.hasOwnProperty(id)) {
var part = this.ppl[id];
delete this.ppl[id];
this.emit("participant removed", part);
this.emit("count", this.countParticipants());
}
};
Client.prototype.findParticipantById = function(id) {
return this.ppl[id] || this.offlineParticipant;
};
Client.prototype.isOwner = function() {
return this.channel && this.channel.crown && this.channel.crown.participantId === this.participantId;
};
Client.prototype.preventsPlaying = function() {
return this.isConnected() && !this.isOwner() && this.getChannelSetting("crownsolo") === true;
};
Client.prototype.receiveServerTime = function(time, echo) {
var self = this;
var now = Date.now();
var target = time - now;
//console.log("Target serverTimeOffset: " + target);
var duration = 1000;
var step = 0;
var steps = 50;
var step_ms = duration / steps;
var difference = target - this.serverTimeOffset;
var inc = difference / steps;
var iv;
iv = setInterval(function() {
self.serverTimeOffset += inc;
if(++step >= steps) {
clearInterval(iv);
//console.log("serverTimeOffset reached: " + self.serverTimeOffset);
self.serverTimeOffset=target;
}
}, step_ms);
// smoothen
//this.serverTimeOffset = time - now; // mostly time zone offset ... also the lags so todo smoothen this
// not smooth:
//if(echo) this.serverTimeOffset += echo - now; // mostly round trip time offset
};
Client.prototype.startNote = function(note, vel) {
if(this.isConnected()) {
var vel = typeof vel === "undefined" ? undefined : +vel.toFixed(3);
if(!this.noteBufferTime) {
this.noteBufferTime = Date.now();
this.noteBuffer.push({n: note, v: vel});
} else {
this.noteBuffer.push({d: Date.now() - this.noteBufferTime, n: note, v: vel});
}
}
};
Client.prototype.stopNote = function(note) {
if(this.isConnected()) {
if(!this.noteBufferTime) {
this.noteBufferTime = Date.now();
this.noteBuffer.push({n: note, s: 1});
} else {
this.noteBuffer.push({d: Date.now() - this.noteBufferTime, n: note, s: 1});
}
}
};

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

293
src/treeMessages.json Normal file
View File

@ -0,0 +1,293 @@
[
"The tree is devoid of fruit.",
"The tree is without fruit.",
"The tree is barren.",
"The tree is missing all its fruit.",
"The tree is not with fruit.",
"The tree is without fruit.",
"The tree is not showing any fruit.",
"The tree is not bearing fruit.",
"The tree has not borne fruit.",
"The tree is not showing fruit.",
"The tree is not carrying fruit.",
"The tree is not holding fruit.",
"The tree is at 0 fruit.",
"The tree has no fruit.",
"The tree doesn't have any fruit to give.",
"The tree doesn't have any fruit to take.",
"The tree doesn't have any fruit left to plunder...",
"The tree has not grown any new fruit.",
"The tree can't give any more fruit right now.",
"The fruit have all been taken.",
"The fruit have all been picked.",
"You don't see any fruit on the tree.",
"Your hand is without fruit. After reaching to pick one",
"No fruit because there aren't any on the tree.",
"No kekklefruit was upon the tree.",
"The tree has long slender limbs, barren of fruit.",
"The tree's limbs are not currently baring any fruit.",
"This tree doesn't have fruit.",
"Fruit are not a thing currently on the tree.",
"Could not get fruit.",
"Try again, please.",
"(no fruit picked)",
"It just doesn't have any fruit.",
"There aren't any fruit.",
"Can't get fruit, there's no fruit.",
"The tree's not growing!!!!!!!",
"Give the tree some time to grow fruit.",
"The tree will grow fruit given time.",
"The tree will have fruit again.",
"The tree's just sitting there. Fruitless.",
"It'll grow fruit, give it a second.",
"Keep trying, but wait until the tree has fruit.",
"Wait until the tree has fruit.",
"Pick again in a bit because the tree doesn't have any fruit right now.",
"There aren't any fruit on the kekklefruit tree",
"You pore over each branch meticulously looking for fruit, but are still coming back empty.",
"You scour every branch of the tree for fruit, but still came back empty-handed.",
"You try caressing the tree's body. It didn't work.",
"You try tugging on one of the branches. It doesn't work.",
"You started picking the fruit when you heard a sound or something that distracted you and made you forget what you were doing. Then, you remember: you tried to pick a fruit. You take a deep breath and decide to try again",
"You could have sworn you were wrapping your hand around a sweet kekklefruit, but it seemingly disappeared from reality right as you grasped it??",
"No fruit.",
"Trying again, there were no fruit to pick.",
"There were no fruit to pick.",
"There was no fruit for you to pick.",
"There isn't anything that looks like a fruit growing on the tree, yet...",
"The fruit just isn't edible yet.",
"It's not ready, keep trying though.",
"It's not ready...!",
"It's not done.",
"Wait, give it time to grow fruit.",
"Just wait for the fruit to grow.",
"Wait for the fruit to grow. But don't wait until someone else grabs it first.",
"You have to give the precious kekklefruits time to grow.",
"Hold on, they're growing.",
"Hold on.",
"Watch the kekklefruit to make sure they have grown before picking them from the tree.",
"Don't pick the kekklefruit until they're grown.",
"The kekklefruit are still maturing.",
"There isn't a pickable kekklefruit.",
"You don't see any.",
"I don't see any.",
"It's like every time the tree grows fruit somebody is stealing it.",
"Every time the tree grows fruit, somebody picks it.",
"There's no fruit, so wait.",
"Keep trying to get fruit.",
"The fruit will be fine... when it grows.",
"The fruit will do fine. Then, pick it.",
"The fruit looks like you could almost pick it!",
"Picking is not available right now.",
"Please try again later.",
"No fruit.",
"Look here. Look there. No fruit anywhere.",
"The fruit just isn't there to pick.",
"You can't pick the fruit because it's not ready to be picked.",
"Don't pick the fruit until it finishes growing into a pickable fruit.",
"Let the fruit grow, first.",
"The tree is out of fruit.",
"The tree's fruit count remains 0.",
"Tree fruit unavailable.",
"You try, but there's no fruit.",
"The tree ran out of fruit.",
"No pickable fruit.",
"People took the tree's fruit.",
"The tree was picked over entirely.",
"The tree just didn't have any more fruit to give.",
"The tree asked you to try again, please.",
"The tree branches looked sinister with no fruit on them at all.",
"Without its fruit, the tree looks kinda scary.",
"The tree doesn't have fruit anymore.",
"The tree doesn't have fruit anymore. It looks weird that way.",
"The tree's long slender branches reached high into the sky, looking nude without their fruit.",
"Robbed of its precious fruit, the tree loomed despondently.",
"The tree doesn't \"have\" fruit.",
"After much consideration, you decide to maybe sayer a prayer for the tree.",
"The action you have taken upon the tree was fruitless.",
"No fruit, just now, not on the tree, here.",
"You didn't get any fruit.",
"The tree's fruit supply is depleted.",
"This tree has a strange animosity.",
"They took it all.",
"There's no more fruit.",
"Don't have any fruit.",
"You just have to wait for kekklefruit.",
"Wait for fruit.",
"Wait for fruit growth.",
"Wait for the fruit growth.",
"Wait for fruit to grow on the tree.",
"Those tree fruit are just hard to come by right now.",
"I haven't seen a fruit",
"It didn't produce fruit yet.",
"You're still waiting for it to produce fruit.",
"You're still waiting for fruit to grow.",
"The tree is bone dry! Sans fruit!",
"God, you'd do anything for a fruit. But not yet.",
"Just be patient.",
"Be patient.",
"Wait patiently for fruit.",
"Your fruit will grow, just wait.",
"Waiting for your fruit to grow.",
"Pick the next fruit that grows.",
"Pick a fruit after it grows.",
"Get a fruit from the tree after they grow.",
"Pick again after the tree has had time to grow fruit.",
"Not yet, it's hasn't grown fruit yet.",
"Wait a second, no fruit yet.",
"You can has fruit after it grows.",
"Try again repeatedly to see if you get a fruit or not.",
"Try again, it grows fruit periodically.",
"Wait",
"No fruit just yet",
"No fruit yet",
"Noooot yet",
"Just a little longer.",
"Wait between each pick for fruit to grow.",
"After a wait, fruit will grow on the tree.",
"The tree's gonna grow plenty of fruit, just give it time.",
"Without its fruit, this tree is looking slightly eerie.",
"What a funny-looking tree without its fruit!",
"You notice the way the tree looks without fruit.",
"You notice the tree looks kinda odd with no fruit like that.",
"You don't like looking at the tree when it doesn't have fruit.",
"You express your desire for the tree to grow fruit.",
"You're waiting for the fruit to grow so you can pick it.",
"Ugh, no fruit..",
"Keep trying to get fruit.",
"The fruit gave under the forces... I guess it wasn't ready yet.",
"The fruit's branches hadn't decided to tree yet.",
"The fruit wasn't available.",
"It's almost time for a fruit to be pickable.",
"Should be a fruit pickable soon.",
"It'll grow fruit for you to pick in a minute.",
"It'll grow in a minute.",
"It'll grow.",
"It'll grow fruit.",
"The fruit will grow on the tree's BRANCHES.",
"You don't spy any fruit on the tree's branches.",
"The tree's branches can be seen in detail without the fruit interrupting our view.",
"You make sure, and there's no fruit on the tree.",
"You search the tree for fruit, and are 100% sure there are none.",
"You're 100% sure there aren't any pickable fruit yet.",
"You try, but don't find any fruit.",
"You look, but don't find any fruit.",
"Can't see any FRUIT.",
"Couldn't /pick",
"It's just that there aren't any fruit on the tree.",
"These things take time.",
"These things can sometimes take time.",
"You can't rush these things.",
"You practice picking the fruit (there aren't any on the tree)",
"It doesn't look like there are any fruit on the tree.",
"0 kinds of fruit are growing on this tree",
"You feel good about the possibility of fruit growing on the tree eventually.",
"You whisper for the tree to grow nice fruits.",
"This is exciting! It'll grow fruit that you can eat.",
"Alas, the tree wasn't currently displaying any fruit.",
"Any fruit on the tree? No...",
"No fruit? Okay...",
"A quick scan shows no fruits on the tree that are ready for picking.",
"You check and don't see any fruit.",
"You give the tree a once-over to see if any fruit area ready. Not yet, but you are resolute...",
"You check on the tree. No fruit, back to whatever it was you were doing.",
"If this tree doesn't grow fruit soon you might start to get crazy.",
"Actually, what if the tree doesn't grow any more fruit?",
"What if the fruit never grows again?",
"Ok, there's no fruit.",
"You consider again what might happen if the fruit stopped growing.",
"There is no fruit, so you just ponder about the tree.",
"There's no fruit, so you just consider it for a moment.",
"There's no fruit, so you think about the tree situation for another moment and then move on.",
"There are no fruits, so you decided to talk about something else.",
"Missed!",
"Didn't chance upon a fruit.",
"Didn't find the fruit.",
"No fruit found.",
"It's gonna be good fruit.",
"The fruit from the tree will never change.",
"The fruit from this tree will always grow, as long as the tree stands, at a pretty steady rate.",
"You survey the tree for fruit, coming back empty-handed.",
"It's not like the tree is on strike from producing fruit.",
"The valuable fruit are not present.",
"The revered fruit have been lost.",
"You study the tree's fruitless branches.",
"Good view of the branches with no fruit on them.",
"Patiently and rapidly retry your command.",
"You use a phone app to make sure the tree doesn't have any pickable fruit.",
"You scan each fruit, finding no candidates for picking.",
"The fruit of the tree are too young and supple to pick.",
"You can't reach that one fruit up there.",
"Oh, there's one. But you can't reach it.",
"You trying to pick fruit that isn't there.",
"Where do you see fruit?",
"Looks like the fruit aren't out today.",
"You wonder what the fruit are doing.",
"You wonder when the tree will bear fruit.",
"You wonder when a fruit will be ready.",
"You wonder if a fruit will grow.",
"You think about how many fruits this tree must have produced with nobody even counting it or anything.",
"You wonder how many fruit this tree has grown in its lifetime.",
"It's not that time, yet.",
"It's not time.",
"Not... yet.",
"The auto-analysis didn't show any completed fruit.",
"The fruit aren't complete.",
"Waiting for fruit growth completion.",
"Please wait for the fruit to be ready.",
"Don't rush it.",
"Slow down, there aren't any fruit to pick yet.",
"You check the fruit indicator under your favorite kekklefruit tree. It reads: 0.",
"Nope, don't see any.",
"Is something taking all the fruit?",
"I guess somebody else picked the fruit first.",
"Somebody else got to it first.",
"This",
"If you focus, the fruit grows faster.",
"You meditate to make the fruit grow faster.",
"What you are doing doesn't make the fruit grow.",
"Don't be too greedy.",
"Fruit pick intercepted.",
"Intercepted, try again.",
"Denied. Try again for success.",
"False success message, no fruit actually picked",
"I swear it'll grow fruit eventually lol",
"You don't know how long it'll take before fruit grows on the tree.",
"You don't know how long before the fruit will grow on the tree.",
"Nobody knows how long it takes for fruit to grow on the tree.",
"The tree says 'no'",
"No fruit, but that's okay.",
"Don't worry about it.",
"No fruit but it's quite alright.",
"No fruit right now.",
"Not a good time to pick fruit.",
"It's probably not a good idea",
"Ha ha don't worry!",
"Lol don't sweat it",
"It's alright! It's just a temporary lack of fruit!",
"Seems like famine again",
"What's wrong with the tree?",
"Is the tree okay?",
"What's this tree for...?",
"Is something wrong with the tree?",
"Try singing the tree a song.",
"The tree doesn't look like it's up to it righ tnow.",
"The tree doesn't look so good.",
"The tree doesn't feel so good.",
"The tree doesn't look like it feels so good.",
"The tree isn't ready right now!",
"Back off and give the tree some time!!",
"Hands off until the tree grows fruit.",
"Patience.",
"Impatience.",
"no",
"Fruit not available",
"There are no fruits there.",
"No fruits upon the tree!",
"That didn't work.",
"Nope, no fruit.",
"You thought you spied a fruit, but were unable to procure any.",
"You climb all over that tree and don't find a single pickable",
"You wouldn't steal a fruit from a tree with no fruit.",
"Are you sure there aren't any fruit just lying around on the ground that you can /take?"
]