Start working on emotes
This commit is contained in:
parent
0f9bfe1429
commit
53138fe1f0
154
lib/channel.js
154
lib/channel.js
|
@ -103,6 +103,7 @@ function Channel(name) {
|
||||||
html: "" // Filtered MOTD text (XSS removed; \n replaced by <br>)
|
html: "" // Filtered MOTD text (XSS removed; \n replaced by <br>)
|
||||||
};
|
};
|
||||||
self.filters = DEFAULT_FILTERS;
|
self.filters = DEFAULT_FILTERS;
|
||||||
|
self.emotes = [];
|
||||||
self.logger = new Logger.Logger(path.join(__dirname, "../chanlogs",
|
self.logger = new Logger.Logger(path.join(__dirname, "../chanlogs",
|
||||||
self.uniqueName + ".log"));
|
self.uniqueName + ".log"));
|
||||||
self.css = ""; // Up to 20KB of inline CSS
|
self.css = ""; // Up to 20KB of inline CSS
|
||||||
|
@ -264,6 +265,15 @@ Channel.prototype.loadState = function () {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Emotes
|
||||||
|
if ("emotes" in data) {
|
||||||
|
data.emotes.forEach(function (e) {
|
||||||
|
self.emotes.push(e);
|
||||||
|
});
|
||||||
|
|
||||||
|
self.updateEmote({ name: ":test:", source: ":test:", image: "http://imgs.xkcd.com/comics/mobile_marketing.png" });
|
||||||
|
}
|
||||||
|
|
||||||
// MOTD
|
// MOTD
|
||||||
if ("motd" in data) {
|
if ("motd" in data) {
|
||||||
self.motd = {
|
self.motd = {
|
||||||
|
@ -315,6 +325,7 @@ Channel.prototype.saveState = function () {
|
||||||
opts: self.opts,
|
opts: self.opts,
|
||||||
permissions: self.permissions,
|
permissions: self.permissions,
|
||||||
filters: filters,
|
filters: filters,
|
||||||
|
emotes: self.emotes,
|
||||||
motd: self.motd,
|
motd: self.motd,
|
||||||
playlistLock: self.playlistLock,
|
playlistLock: self.playlistLock,
|
||||||
chatbuffer: self.chatbuffer,
|
chatbuffer: self.chatbuffer,
|
||||||
|
@ -555,6 +566,7 @@ Channel.prototype.join = function (user) {
|
||||||
self.sendMediaUpdate([user]);
|
self.sendMediaUpdate([user]);
|
||||||
self.sendPlaylistLock([user]);
|
self.sendPlaylistLock([user]);
|
||||||
self.sendUserlist([user]);
|
self.sendUserlist([user]);
|
||||||
|
self.sendEmoteList([user]);
|
||||||
self.sendRecentChat([user]);
|
self.sendRecentChat([user]);
|
||||||
self.sendCSSJS([user]);
|
self.sendCSSJS([user]);
|
||||||
self.sendPoll([user]);
|
self.sendPoll([user]);
|
||||||
|
@ -1013,6 +1025,16 @@ Channel.prototype.sendChatFilters = function (users) {
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sends the emote list
|
||||||
|
*/
|
||||||
|
Channel.prototype.sendEmoteList = function (users) {
|
||||||
|
var self = this;
|
||||||
|
users.forEach(function (u) {
|
||||||
|
u.socket.emit("emoteList", self.emotes);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sends the channel permissions
|
* Sends the channel permissions
|
||||||
*/
|
*/
|
||||||
|
@ -2444,6 +2466,138 @@ Channel.prototype.handleMoveFilter = function (user, data) {
|
||||||
this.moveFilter(data.from, data.to);
|
this.moveFilter(data.from, data.to);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Imports a list of emotes, replacing the current list
|
||||||
|
*/
|
||||||
|
Channel.prototype.importEmotes = function (emotes) {
|
||||||
|
this.emotes = emotes;
|
||||||
|
this.sendEmoteList(this.users);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handles a user message to import a list of emotes
|
||||||
|
*/
|
||||||
|
Channel.prototype.handleImportEmotes = function (user, data) {
|
||||||
|
if (!this.hasPermission(user, "emoteimport")) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(data instanceof Array)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.emotes = data.map(this.validateEmote.bind(this))
|
||||||
|
.filter(function (f) { return f !== false; });
|
||||||
|
|
||||||
|
this.sendEmoteList(this.users);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Validates data for an emote
|
||||||
|
*/
|
||||||
|
Channel.prototype.validateEmote = function (f) {
|
||||||
|
if (typeof f.source !== "string" || typeof f.image !== "string") {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (typeof f.name !== "string") {
|
||||||
|
f.name = f.source;
|
||||||
|
}
|
||||||
|
|
||||||
|
f.image = f.image.substring(0, 1000);
|
||||||
|
f.image = XSS.sanitizeText(f.image);
|
||||||
|
|
||||||
|
try {
|
||||||
|
new RegExp(f.regex, "gi");
|
||||||
|
} catch (e) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return f;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Updates an emote, or adds a new one if the emote does not exist
|
||||||
|
*/
|
||||||
|
Channel.prototype.updateEmote = function (emote) {
|
||||||
|
var self = this;
|
||||||
|
|
||||||
|
if (!emote.name) {
|
||||||
|
emote.name = emote.source;
|
||||||
|
}
|
||||||
|
|
||||||
|
var found = false;
|
||||||
|
for (var i = 0; i < self.emotes.length; i++) {
|
||||||
|
if (self.emotes[i].name === emote.name) {
|
||||||
|
found = true;
|
||||||
|
self.emotes[i] = emote;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!found) {
|
||||||
|
self.emotes.push(emote);
|
||||||
|
}
|
||||||
|
|
||||||
|
self.users.forEach(function (u) {
|
||||||
|
u.socket.emit("updateEmote", emote);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handles a user message to update an emote
|
||||||
|
*/
|
||||||
|
Channel.prototype.handleUpdateEmote = function (user, f) {
|
||||||
|
if (!this.hasPermission(user, "emoteedit")) {
|
||||||
|
user.kick("Attempted updateEmote with insufficient permission");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var emote = this.validateEmote(f);
|
||||||
|
if (!emote) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.logger.log("[mod] " + user.name + " updated emote: " + f.name + " -> " +
|
||||||
|
f.image);
|
||||||
|
this.updateEmote(emote);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Removes an emote
|
||||||
|
*/
|
||||||
|
Channel.prototype.removeEmote = function (emote) {
|
||||||
|
var self = this;
|
||||||
|
|
||||||
|
for (var i = 0; i < self.emotes.length; i++) {
|
||||||
|
if (self.emotes[i].name === emote.name) {
|
||||||
|
self.emotes.splice(i, 1);
|
||||||
|
self.users.forEach(function (u) {
|
||||||
|
u.socket.emit("deleteEmote", emote);
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handles a user message to delete an emote
|
||||||
|
*/
|
||||||
|
Channel.prototype.handleRemoveEmote = function (user, f) {
|
||||||
|
if (!this.hasPermission(user, "emoteedit")) {
|
||||||
|
user.kick("Attempted removeEmote with insufficient permission");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (typeof f.name !== "string") {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.logger.log("[mod] " + user.name + " removed emote: " + f.name);
|
||||||
|
this.removeFilter(f);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handles a user message to change the channel permissions
|
* Handles a user message to change the channel permissions
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -1032,7 +1032,31 @@ Callbacks = {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
|
|
||||||
|
emoteList: function (data) {
|
||||||
|
loadEmotes(data);
|
||||||
|
},
|
||||||
|
|
||||||
|
updateEmote: function (data) {
|
||||||
|
data.regex = new RegExp(data.source, "gi");
|
||||||
|
var found = false;
|
||||||
|
for (var i = 0; i < CHANNEL.emotes.length; i++) {
|
||||||
|
if (CHANNEL.emotes[i].name === data.name) {
|
||||||
|
found = true;
|
||||||
|
CHANNEL.emotes[i] = data;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!found) {
|
||||||
|
CHANNEL.emotes.push(data);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
deleteEmote: function (data) {
|
||||||
|
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
var SOCKET_DEBUG = true;
|
var SOCKET_DEBUG = true;
|
||||||
|
|
|
@ -32,7 +32,8 @@ var CHANNEL = {
|
||||||
motd: "",
|
motd: "",
|
||||||
motd_text: "",
|
motd_text: "",
|
||||||
name: false,
|
name: false,
|
||||||
usercount: 0
|
usercount: 0,
|
||||||
|
emotes: []
|
||||||
};
|
};
|
||||||
|
|
||||||
var PLAYER = false;
|
var PLAYER = false;
|
||||||
|
|
|
@ -1270,6 +1270,8 @@ function formatChatMessage(data) {
|
||||||
if (data.meta.forceShowName)
|
if (data.meta.forceShowName)
|
||||||
skip = false;
|
skip = false;
|
||||||
|
|
||||||
|
data.msg = execEmotes(data.msg);
|
||||||
|
|
||||||
LASTCHATNAME = data.username;
|
LASTCHATNAME = data.username;
|
||||||
LASTCHATTIME = data.time;
|
LASTCHATTIME = data.time;
|
||||||
var div = $("<div/>");
|
var div = $("<div/>");
|
||||||
|
@ -2180,3 +2182,24 @@ function formatUserPlaylistList() {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function loadEmotes(data) {
|
||||||
|
CHANNEL.emotes = [];
|
||||||
|
data.forEach(function (e) {
|
||||||
|
e.regex = new RegExp(e.source, "gi");
|
||||||
|
CHANNEL.emotes.push(e);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function execEmotes(msg) {
|
||||||
|
if (USEROPTS.no_emotes) {
|
||||||
|
return msg;
|
||||||
|
}
|
||||||
|
|
||||||
|
CHANNEL.emotes.forEach(function (e) {
|
||||||
|
msg = msg.replace(e.regex, '<img class="channel-emote" src="' +
|
||||||
|
e.image + '" title="' + e.name + '">');
|
||||||
|
});
|
||||||
|
|
||||||
|
return msg;
|
||||||
|
}
|
||||||
|
|
|
@ -483,3 +483,8 @@ li.ui-sortable-helper, li.ui-sortable-placeholder + li.queue_entry {
|
||||||
border-top-left-radius: 0;
|
border-top-left-radius: 0;
|
||||||
border-top-right-radius: 0;
|
border-top-right-radius: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.channel-emote {
|
||||||
|
max-width: 200px;
|
||||||
|
max-height: 200px;
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue