Finished tokebot implementation. tz and of tokes decapitalized and

consolidated, !r added, toke log and  per user toke count tracking. Toke
count on tooltip. Improved moderator commands & tokebot output
formatting.
This commit is contained in:
rainbownapkin 2022-07-23 09:24:19 +00:00
parent 46bcb040f2
commit fcb562397a
8 changed files with 389 additions and 49 deletions

View file

@ -200,15 +200,29 @@ dev goals for 1.1 pineapple express:
- merge tokebot into ourfore.st codebase, one server instead of two.
- port chozobot code to cytube module ✓
- CRITICAL BUG FIX: Duplicate username during callout (test toking on multiple channels, etc...)
- load toke commands from tokes file
- tokewhisper (server whisper, can optionally be displayed as PM client side)
- profile and userlist entry(togglable clientside, on by default)
- bot specific rank
- reset cooldown accessible from modmenu (quiet and loud, quiet by default)
- log tokes w/ date to file. This will be switched to mariadb in the next update
- tokefile, list of usernames with toke count. This will be switched to mariadb in the next update
- total tokes listed on profile tooltip
- tokewhisper (server whisper, can optionally be displayed as PM client side) ✓
- load toke commands from tokes file ✓
- profile and userlist entry ✓
- disable certain options in profile context menu ✓
- mod commands ✓
- reset cooldown command (quiet and loud, quiet by default) ✓
- siteowner commands ✓
- reload tokes command ✓
- tokesay command ✓
- tokeannounce command ✓
- tokewhisper command ✓
- !r to rando-toke ✓
- log tokes w/ date to file. This will be consolidated to a better toke history in mariadb in a future update
- append [tokers],# of tokers,timestamp(epoch) on toke.
- tokefile, list of usernames with toke count. This should eventually be moved to a property of account or user
- json of map ["username", # of tokes] ✓
- load file on startup ✓
- update file every toke ✓
- total tokes listed on profile tooltip ✓
- send toke count with user and set toke count ✓
- display on tooltip ✓
- add toke to profile client side on toke(avoid sending information twice, write after tokes in tooltip) ✓
- include modflair on tokewhisper ✓
- autobump
- sepearate bump lists, based on js/txt files at first, will be stored in db next update (may use multiple at once)
@ -219,17 +233,24 @@ dev goals for 1.1 pineapple express:
- require video be at least 4 minutes to add bump (mods can override from bump menu)
- finishing touches
- CRITICAL BUG FIX: video sometimes unlatches if sync delayed on video start.(Fix pre-latch, if not duration check until sync is past 2s?)
- CRITICAL BUG FIX: userlist profile tooltips are currently broken
- CRITICAL BUG FIX: chat does not fill screen in portrait mode (video height being subtracted while video collapsed)
- Critical Bug Fix: video sometimes unlatches if sync delayed on video start.(Fix pre-latch, if not duration check until sync is past 2s?)
- Critical Bug Fix: userlist profile & current connected users tooltips are currently broken ✓
- Critical Bug Fix: chat does not fill screen in portrait mode (video height being subtracted while video collapsed)
- Critical Bug Fix: make serverside commands case insensitive(May have been intentional with cytube, don't give a shit, it's a bug.)
- Critical Bug Fix: serverside commands trigger other commands with same letters (!announce triggers !a)
- Minor Bug Fix: hide "close playlist" button when playlist is in fpanel
- Minor Bug Fix: Execute serverside commands with whitespace before them while also sending them as normal chat to comform to tokebot behavior in (v1)Panama Red
- add scrollTo() on fpplaylist open
- save temporary vids to channel library
- getplaylistlinks outputs in fpanel
- display links
- pop mod nmenu
- css variables in theme for ez customizablity
- import data from old tokelog
- merge fore.st theme changes to fore.st dusk, consider moving some of them over to cytube.css for easier management
- extra shit(probs wait til next update, or hotfix)
- shared tokes across channels
- short chats (acronyms, emoji, single letters/numbers/symbols) pop in over video from left starting at top left, overflow pops in below, instead of in chat box. Chats slide back up into top of vid after 2s. (optional, default on)
- pop out btn
- basic profile page (in side panel)
@ -247,7 +268,9 @@ dev goals for 1.1 pineapple express:
- getres
- update minicont dur
- update minicont buttons
- treez.one Now Playing in MOTD (these will need coordination with treez.one)
- treez.one tokebot syncronization (ESPECIALLY this one)
-
## License
Original fore.st code is provided under the Affero General Public License v3 in order to prevent fore.st being used in proprietary software.
(see the LICENSE file for the full text.)

View file

@ -624,13 +624,18 @@ Channel.prototype.maybeResendUserlist = function maybeResendUserlist(user, newRa
};
Channel.prototype.packUserData = function (user) {
var tc = 0;
if(this.modules.tokebot.statmap != null){
tc = (this.modules.tokebot.statmap.get(user.getName()) == null ? 0 : this.modules.tokebot.statmap.get(user.getName()));
}
var base = {
name: user.getName(),
rank: user.account.effectiveRank,
profile: user.account.profile,
meta: {
afk: user.is(Flags.U_AFK),
muted: user.is(Flags.U_MUTED) && !user.is(Flags.U_SMUTED)
muted: user.is(Flags.U_MUTED) && !user.is(Flags.U_SMUTED),
toke: tc
}
};
@ -643,7 +648,8 @@ Channel.prototype.packUserData = function (user) {
muted: user.is(Flags.U_MUTED),
smuted: user.is(Flags.U_SMUTED),
aliases: user.account.aliases,
ip: user.displayip
ip: user.displayip,
toke: tc
}
};
@ -656,7 +662,8 @@ Channel.prototype.packUserData = function (user) {
muted: user.is(Flags.U_MUTED),
smuted: user.is(Flags.U_SMUTED),
aliases: user.account.aliases,
ip: user.realip
ip: user.realip,
toke: tc
}
};
@ -697,7 +704,6 @@ Channel.prototype.sendUserProfile = function (users, user) {
name: user.getName(),
profile: user.account.profile
};
users.forEach(function (u) {
u.socket.emit("setUserProfile", packet);
});

View file

@ -17,8 +17,12 @@ import fs from 'fs';
var ChannelModule = require("./module");
//global vars
var tokes = loadTokes();
var solotokes = ["", "https://ourfore.st/img/femotes/onetoker.jpg","https://ourfore.st/img/femotes/solotoke.jpg","https://ourfore.st/img/femotes/1toker.gif"];
function loadTokes(){
//global functions
function loadTokes(){//load tokes as array from file
const rawContents = fs.readFileSync("tokebot/tokes").toString('utf8');
var spcReg = /^\s*$/g;
var t = rawContents.split("\n").filter(function(i){
@ -27,12 +31,36 @@ function loadTokes(){
return t;
}
var tokes = loadTokes();
//used to store ES6 maps as arrays in JSON
function mapReplacer(key, value) {
if(value instanceof Map) {
return {
dataType: 'Map',
value: Array.from(value.entries()), // or with spread: value: [...value]
};
} else {
return value;
}
}
function mapReviver(key, value) {
if(typeof value === 'object' && value !== null) {
if (value.dataType === 'Map') {
return new Map(value.value);
}
}
return value;
}
function randi(len) {//get random number from zero to len, meant for use to pull random items from an array
return Math.floor(Math.random() * len); //The maximum is exclusive and the minimum is inclusive
}
//constructor
function TokebotModule(_channel){
ChannelModule.apply(this, arguments);
//mod command registration
this.channel.modules.chat.registerCommand("!resettoke", this.resettoke.bind(this));
@ -45,21 +73,27 @@ function TokebotModule(_channel){
//!toke command registration
this.updatetokes();
this.channel.modules.chat.registerCommand("!r", this.randotoke.bind(this));
this.loadtfile();//load up toke stats from toke file.
}
//protoype definition
TokebotModule.prototype = Object.create(ChannelModule.prototype);
//tokebot object properties
TokebotModule.prototype.toking = 0;
TokebotModule.prototype.tokers = [];
TokebotModule.prototype.cdown = 3;
TokebotModule.prototype.cdel = 120;
TokebotModule.prototype.ctime = 120;
TokebotModule.prototype.solotokes = ["", "https://ourfore.st/img/femotes/onetoker.jpg","https://ourfore.st/img/femotes/solotoke.jpg","https://ourfore.st/img/femotes/1toker.gif"];
TokebotModule.prototype.statmap = null;
//mod commands
TokebotModule.prototype.resettoke = function(user, msg, _meta){
if(user.account.effectiveRank >= 2 && this.toking == 2){
//this.toking = 0;
this.ctime = 0;
this.tokewhisper("!toke cooldown reset.", user.account.name);
}
@ -98,6 +132,11 @@ TokebotModule.prototype.tokewhisperCmd = function(user, msg, _meta){
}
}
//extra user commands
TokebotModule.prototype.randotoke = function(user, msg, _meta){
this.toke(user, '!' + tokes[randi(tokes.length)],_meta);
}
//main toke logic (adapted from chozobot implementation)
TokebotModule.prototype.toke = function (user, msg, _meta){
var name = user.getName()
@ -116,7 +155,7 @@ TokebotModule.prototype.toke = function (user, msg, _meta){
if(this.tokers.includes(name)){
this.tokewhisper(" You're already taking part in this toke!", name);
}else{
this.tokesay("joined the toke! Post " + msg + " to take part!");
this.tokesay(name + " joined the toke! Post " + msg + " to take part!");
this.tokers.push(name);
this.cdown = 3;
}
@ -156,8 +195,9 @@ TokebotModule.prototype.endtoke = function (tb){
tb.tokesay("Take a toke " + callstring + "! " + tb.tokers.length + " tokers!");
}else{
tb.tokesay("Take a toke " + tb.tokers.toString() + ". " + (tb.solotokes[tb.getRandomInt(0,tb.solotokes.length)]));
tb.tokesay("Take a toke " + tb.tokers.toString() + ". " + (solotokes[randi(solotokes.length)]));
}
tb.logtoke();
tb.tokers = [];
tb.toking = 2;//reset toking mode
setTimeout(tb.cooldown, 1000, tb);
@ -181,9 +221,7 @@ TokebotModule.prototype.updatetokes = function (){
tokes = loadTokes();
if(this.channel.modules.chat){//register !toke commands
if(tokes == null){//if for some reason tokes file couldnt be loaded
this.channel.modules.chat.registerCommand("!toke", this.toke.bind(this));
console.log("[tokebot] Unable to load toke commands from ./tokebot/tokes, defaulting to !toke definition");
if(tokes == null){//if for some reason tokes file couldnt be loaded this.channel.modules.chat.registerCommand("!toke", this.toke.bind(this)); console.log("[tokebot] Unable to load toke commands from ./tokebot/tokes, defaulting to !toke definition");
}else{//if we we're able to pull toke commands
var _this = this;//we need to use this, might put this up higher to replace the tb parameter in other member functions
tokes.forEach(function(tokec){
@ -200,7 +238,7 @@ TokebotModule.prototype.tokesay = function (msg,quiet){
meta:{
addClass: (quiet ? null : "shout"),
addClassToNameAndTimestamp: true,
forceShowName: true,
forceShowName: (quiet ? true : false), //It's loud enough when announcing. Toke chats are rare enouhg to be more prominent :P
modflair: 3
},
time: Date.now()
@ -224,10 +262,46 @@ TokebotModule.prototype.tokewhisper = function (msg, usr){//(msg, username)
}
}
TokebotModule.prototype.getRandomInt = function (min, max) {
min = Math.ceil(min);
max = Math.floor(max);
return Math.floor(Math.random() * (max - min) + min); //The maximum is exclusive and the minimum is inclusive
};
//filesystem manipulation functions
TokebotModule.prototype.writetokelog = function(){//append a toke to current channels toke log
var _this = this;
fs.appendFile("tokebot/" + this.channel.name + "_toke.log" ,('[' + this.tokers.toString() + '],' + this.tokers.length + ',' + new Date().getTime() + "\n"), function(err){
if(err){
console.log("[chan: " + _this.channel.name + "] TOKE LOG WRITE ERROR: " + err);
}
});
}
TokebotModule.prototype.loadtfile = function(){//load tokefile into statmap(default to new Map() on error)
var _this = this;
fs.readFile("tokebot/" + this.channel.name + "_tokefile", function(err,data){
if(err){
console.log("[chan: " + _this.channel.name + "] TOKE FILE READ ERROR (may overwrite existing stat file!): " + err);
_this.statmap = new Map();
}else{
_this.statmap = JSON.parse(data, mapReviver);
}
});
}
TokebotModule.prototype.writetfile = function(){//write statmap to tokefile
var _this = this;
fs.writeFile("tokebot/" + this.channel.name + "_tokefile", JSON.stringify(_this.statmap, mapReplacer), function(err,data){
if(err){
console.log("[chan: " + _this.channel.name + "] TOKE FILE WRITE ERROR: " + err);
}
});
}
TokebotModule.prototype.logtoke = function(){
this.writetokelog();//save toke to toke log
var _this = this;
this.tokers.forEach(function (u){//for all tokers
var ct = _this.statmap.get(u);//lets make this a lil prettier :P
_this.statmap.set(u,(ct == null ? 1 : ++ct));//increment toke counter
});
this.writetfile();//write statmap to tfile
}
module.exports = TokebotModule;

View file

@ -30,7 +30,6 @@ hit
tjoke
tjokem
devilslettuce
tokem
toakem
grass
liftoff
@ -71,7 +70,7 @@ justgirlythings
heyrainbowaddthis
inhale
ignite
THEPLANT
theplant
spark
sparkone
sparkem
@ -81,3 +80,220 @@ witness
roastem
crabpeople
shootthemoon
ballmastr
checkitout
brule
strangerthings
strange
silicon
goteamventure
snaildown
high
stoned
drunk
glazzballs
sin
vibe
frittata
breen
soup
robots
love
hootiehoo
pot
toe
feet
foot
science
horse
bagel
roach
ranch
weedistight
mattea
katebush
runningupthathill
running
morbin
yee
maidenless
smellyplants
foryourhealth
cromdar
cbd
yeet
viking
suck
vamp
sparkle
northman
jack
keanu
woof
yote
pizza
dudewhat
wine
red
beer
liquor
ipa
a
c
d
x
y
z
n
rat
smeg
meg
kegels
greasy
bullshitartist
spear
fang
brutal
dethklok
goodbye
tab
jfc
ghost
burger
toad
snek
pill
2count
doobie
dooby
yeehaw
debra
tree
69
311
buttstonked
trees
treez
plants
plantz
aliens
ollie
greatscott
121gigawatts
88mph
smokeweedblazeit
smek
cry
smook
justdudethings
oscarfever
007
kiff
kief
jeff
gay
lesbian
bi
trans
queer
meow
tocar
fumar
ruhroh
spoop
tok
fight
club
stab
otke
greatergood
toker
tokes
toked
twunk
twonk
doublerainbow
kava
kratom
catjam
fuck
squanch
snortskie
zoinks
luckoftheirish
comeondown
ihaventeventriedityet
warter
water
death
dead
smokeweed
quack
clurb
coffee
duck
cum
nut
bong
piss
smok
basmati
meds
vitamins
protein
blazem", //^og tok
squirt
drinkwater
chug
olympic
marihuana
hooray
flambe
flambé
tenturnyourrainsoundsoff
jabroni
lame
yoke
reefer
bloke
hailsanta
tonks
henshin
maryjane
fart
shart
jinkies
whatastorymark
ohhaimark
cheep
bat
bats
batman
birdgirl
himbo
t
o
k
e
b
popcorn
puppy
puppybowl
superbowl
super
bowl
owl
kitty
crab
rso
drugs
drugz
spacesurf
birdup
eltoke
thistooshallpass
beber
wrasslin
her
yikes
booyak

View file

@ -192,6 +192,7 @@ body{
display: flex;
flex-wrap: wrap;
align-items: center;
z-index: 2;
}
#chatheader > p, #videowrap-header {

View file

@ -522,11 +522,27 @@ Callbacks = {
},
chatMsg: function(data) {
if(data.username === "tokebot" && data.meta.addClass === "server-whisper" && USEROPTS.toke_pm){
data.meta = {};
if(data.username === "tokebot"){
console.log(data);
if(data.meta.addClass === "server-whisper"){
data.meta.modflair = 3;
if( USEROPTS.toke_pm){
data.meta = {
modflair: 3
};
window.Callbacks.pm(data);
return;
}
}else if(data.meta.addClass === "shout" && data.msg.startsWith("Take a toke")){
data.msg.split(" ").forEach(function(w){
var n = w.slice(0,-1);
if(usrColors[0].includes(n)){
$(".userlist_" + n).data().meta.toke++;
}
});
}
}
addChatMessage(data);
},
@ -577,7 +593,6 @@ Callbacks = {
addUser: function(data) {
CyTube._internal_do_not_use_or_you_will_be_banned.addUserToList(data, true);
console.log(data);
sortUserlist();
},

View file

@ -207,8 +207,8 @@ $("#usercount").mousemove(function (ev) {
if(popup.length == 0)
return;
popup.css("top", (ev.clientY + 5) + "px");
popup.css("left", (ev.clientX - 120) + "px");
popup.css("top", (ev.clientY + 5) - $("#usercount").parent().offset().top + "px");
popup.css("left", (ev.clientX - 120) - $("#usercount").parent().offset().left + "px");
});
$("#usercount").mouseleave(function () {

View file

@ -184,6 +184,9 @@ function formatUserlistItem(div) {
$("<br/>").appendTo(profile);
$("<em/>").text(meta.ip).appendTo(profile);
}
$("<br/>").appendTo(profile);
$("<em/>").text("tokes: " + div.data().meta.toke).appendTo(profile);
if (meta.aliases) {
$("<br/>").appendTo(profile);
$("<em/>").text("aliases: " + meta.aliases.join(", ")).appendTo(profile);
@ -195,10 +198,11 @@ function formatUserlistItem(div) {
profile.css("left", horiz + "px")
});
name.mousemove(function(ev) {
var top = ev.clientY + 5;
var horiz = ev.clientX;
if ($("body").hasClass("synchtube")) horiz -= profile.outerWidth();
var top = ev.clientY + 5 - div.parent().offset().top;
var horiz = ev.clientX - div.offset().left;
//if ($("body").hasClass("synchtube")) horiz -= profile.outerWidth();
profile.css("left", horiz + "px")
.css("top", top + "px");
});
@ -494,10 +498,11 @@ function sortUserlist() {
},
meta: {
afk: false,
aliases: [],
aliases: ["tokebot"],
ip: "127.0.0.1",
muted: false,
smuted: false
smuted: false,
toke: '∞'
}
}
);
@ -3555,7 +3560,7 @@ CyTube._internal_do_not_use_or_you_will_be_banned.addUserToList = function (data
}
assignColors(data.name);
var div = $("<div/>")
.addClass("userlist_item").attr('id', getColor(data.name));
.addClass("userlist_item").addClass("userlist_" + data.name).attr('id', getColor(data.name));
var icon = $("<span/>").appendTo(div);
var nametag = $("<span/>").text(data.name).appendTo(div);
div.data("name", data.name);