Merge branch 'dev'
このコミットが含まれているのは:
コミット
e68bf56c9b
|
@ -114,7 +114,7 @@ def add_chat_message(user, nonce, comment, ignore_empty=False):
|
||||||
# Deverify user every n messages
|
# Deverify user every n messages
|
||||||
if CONFIG['CHAT_DEVERIFY_CLOCK'] is not None:
|
if CONFIG['CHAT_DEVERIFY_CLOCK'] is not None:
|
||||||
user['clock'] = (user['clock'] + 1) % CONFIG['CHAT_DEVERIFY_CLOCK']
|
user['clock'] = (user['clock'] + 1) % CONFIG['CHAT_DEVERIFY_CLOCK']
|
||||||
if user['clock'] == 0:
|
if user['clock'] == 0 and not user['broadcaster']:
|
||||||
user['verified'] = False
|
user['verified'] = False
|
||||||
|
|
||||||
# Notify event sockets that a chat message was added
|
# Notify event sockets that a chat message was added
|
||||||
|
|
|
@ -169,5 +169,6 @@ def toml_to_flask_section_nojs(config):
|
||||||
def toml_to_flask_section_emote(config):
|
def toml_to_flask_section_emote(config):
|
||||||
cfg = config['emote']
|
cfg = config['emote']
|
||||||
return {
|
return {
|
||||||
|
'EMOTE_SHEET': cfg['sheet'],
|
||||||
'EMOTE_SCHEMA': cfg['schema'],
|
'EMOTE_SCHEMA': cfg['schema'],
|
||||||
}
|
}
|
||||||
|
|
|
@ -55,6 +55,7 @@ async def nojs_chat_messages(timestamp, user):
|
||||||
user=user,
|
user=user,
|
||||||
users_by_token=USERS_BY_TOKEN,
|
users_by_token=USERS_BY_TOKEN,
|
||||||
emotes=EMOTES,
|
emotes=EMOTES,
|
||||||
|
emotesheet=CONFIG['EMOTE_SHEET'],
|
||||||
emotehash=get_emotehash(tuple(EMOTES)),
|
emotehash=get_emotehash(tuple(EMOTES)),
|
||||||
messages=get_scrollback(current_app.messages),
|
messages=get_scrollback(current_app.messages),
|
||||||
timeout=CONFIG['NOJS_TIMEOUT_CHAT'],
|
timeout=CONFIG['NOJS_TIMEOUT_CHAT'],
|
||||||
|
|
|
@ -284,26 +284,26 @@ const delete_chat_messages = (seqs) => {
|
||||||
|
|
||||||
const hexdigest = async (string, bytelength) => {
|
const hexdigest = async (string, bytelength) => {
|
||||||
uint8array = new TextEncoder().encode(string);
|
uint8array = new TextEncoder().encode(string);
|
||||||
arraybuffer = await crypto.subtle.digest('sha-256', uint8array);
|
arraybuffer = await crypto.subtle.digest("sha-256", uint8array);
|
||||||
array = Array.from(new Uint8Array(arraybuffer).slice(0, bytelength));
|
array = Array.from(new Uint8Array(arraybuffer).slice(0, bytelength));
|
||||||
hex = array.map(b => b.toString(16).padStart(2, '0')).join('');
|
hex = array.map(b => b.toString(16).padStart(2, "0")).join("");
|
||||||
return hex
|
return hex
|
||||||
}
|
}
|
||||||
const escape_css_string = (string) => {
|
const escape_css_string = (string) => {
|
||||||
/* https://drafts.csswg.org/cssom/#common-serializing-idioms */
|
/* https://drafts.csswg.org/cssom/#common-serializing-idioms */
|
||||||
const result = [];
|
const result = [];
|
||||||
for (const char of string) {
|
for (const char of string) {
|
||||||
if (char === '\0') {
|
if (char === "\0") {
|
||||||
result.push('\ufffd');
|
result.push("\ufffd");
|
||||||
} else if (char < '\u0020' || char == '\u007f') {
|
} else if (char < "\u0020" || char == "\u007f") {
|
||||||
result.push(`\\${char.charCodeAt().toString(16)}`);
|
result.push(`\\${char.charCodeAt().toString(16)}`);
|
||||||
} else if (char == '"' || char == '\\') {
|
} else if (char == '"' || char == "\\") {
|
||||||
result.push(`\\${char}`);
|
result.push(`\\${char}`);
|
||||||
} else {
|
} else {
|
||||||
result.push(char);
|
result.push(char);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return result.join('');
|
return result.join("");
|
||||||
}
|
}
|
||||||
const update_emotes = async (emotes) => {
|
const update_emotes = async (emotes) => {
|
||||||
const rules = [];
|
const rules = [];
|
||||||
|
@ -315,7 +315,7 @@ const update_emotes = async (emotes) => {
|
||||||
}
|
}
|
||||||
rules.sort();
|
rules.sort();
|
||||||
const emotehash = await hexdigest(rules.toString(), 6);
|
const emotehash = await hexdigest(rules.toString(), 6);
|
||||||
const emotehash_rule = `.emote { background-image: url("/static/emotes.png?coords=${escape_css_string(encodeURIComponent(emotehash))}"); }`;
|
const emotehash_rule = `.emote { background-image: url("/static/${escape_css_string(escape(emotesheet))}?coords=${escape_css_string(encodeURIComponent(emotehash))}"); }`;
|
||||||
|
|
||||||
const rules_set = new Set([emotehash_rule, ...rules]);
|
const rules_set = new Set([emotehash_rule, ...rules]);
|
||||||
const to_delete = [];
|
const to_delete = [];
|
||||||
|
@ -337,6 +337,7 @@ let users = {};
|
||||||
let stats = null;
|
let stats = null;
|
||||||
let stats_received = null;
|
let stats_received = null;
|
||||||
let default_name = {true: "Broadcaster", false: "Anonymous"};
|
let default_name = {true: "Broadcaster", false: "Anonymous"};
|
||||||
|
let emotesheet = "emotes.png";
|
||||||
let max_chat_scrollback = 256;
|
let max_chat_scrollback = 256;
|
||||||
let pingpong_period = 8.0;
|
let pingpong_period = 8.0;
|
||||||
let ping = null;
|
let ping = null;
|
||||||
|
@ -734,7 +735,8 @@ const on_websocket_message = async (event) => {
|
||||||
chat_appearance_form_name.setAttribute("placeholder", default_name[user.broadcaster]);
|
chat_appearance_form_name.setAttribute("placeholder", default_name[user.broadcaster]);
|
||||||
chat_appearance_form_color.setAttribute("value", user.color);
|
chat_appearance_form_color.setAttribute("value", user.color);
|
||||||
|
|
||||||
// emote coordinates
|
// emotes
|
||||||
|
emotesheet = receipt.emotesheet;
|
||||||
await update_emotes(receipt.emotes);
|
await update_emotes(receipt.emotes);
|
||||||
|
|
||||||
// insert new messages
|
// insert new messages
|
||||||
|
|
|
@ -134,7 +134,7 @@
|
||||||
line-height: 1.3125;
|
line-height: 1.3125;
|
||||||
}
|
}
|
||||||
.emote {
|
.emote {
|
||||||
background-image: url("{{ escape_css_string(url_for('static', filename='emotes.png', coords=emotehash)) | safe }}");
|
background-image: url("{{ escape_css_string(url_for('static', filename=emotesheet, coords=emotehash)) | safe }}");
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
font-size: 0;
|
font-size: 0;
|
||||||
vertical-align: middle;
|
vertical-align: middle;
|
||||||
|
|
|
@ -38,6 +38,7 @@ async def websocket_outbound(queue, user):
|
||||||
'digest': get_random_captcha_digest_for(user),
|
'digest': get_random_captcha_digest_for(user),
|
||||||
'pingpong': CONFIG['TASK_BROADCAST_PING'],
|
'pingpong': CONFIG['TASK_BROADCAST_PING'],
|
||||||
'emotes': get_emotes_for_websocket(),
|
'emotes': get_emotes_for_websocket(),
|
||||||
|
'emotesheet': CONFIG['EMOTE_SHEET'],
|
||||||
})
|
})
|
||||||
while True:
|
while True:
|
||||||
payload = await queue.get()
|
payload = await queue.get()
|
||||||
|
|
|
@ -91,4 +91,5 @@ refresh_users = 6.0
|
||||||
timeout_chat = 30.0
|
timeout_chat = 30.0
|
||||||
|
|
||||||
[emote]
|
[emote]
|
||||||
|
sheet = "emotes.png"
|
||||||
schema = "emotes.json"
|
schema = "emotes.json"
|
||||||
|
|
読み込み中…
新しいイシューから参照