// ==UserScript==
// @name DH3 chat overhaul
// @namespace FileFace
// @version 2.5.5.3
// @description lol
// @author shtos
// @match dh3.diamondhunt.co
// @grant none
// ==/UserScript==
/*jshint multistr: true */
/*jslint es5: true */
(function() {
'use strict';
const dhEmoji = ['sapphire','emerald','ruby','diamond','bloodDiamond','combatSkill','magicSkill','miningSkill','craftingSkill','woodcuttingSkill','farmingSkill','brewingSkill','fishingSkill','cookingSkill']
const pots = [{name: 'stardust', xp: 50},
{name: 'sand', xp: 80},
{name: 'cookingBoost', xp:70},
{name: 'combatCooldown', xp: 210},
{name: 'compost', xp: 140},
{name: 'oil', xp: 80},
{name: 'bone', xp: 100},
{name: 'treeStarter', xp: 160},
{name: 'repelPotion1', xp: 1500},
{name: 'bar', xp: 600},
{name: 'sapphireStardust', xp: 450},
{name: 'mana', xp: 5000},
{name: 'largeStardust', xp: 4400},
{name: 'largeFurnace', xp: 1850},
{name: 'largePirate', xp: 1900},
{name: 'largeEmeraldStardust', xp: 6600},
{name: 'largeRocketSpeed', xp: 4100},
{name: 'repelPotion2', xp: 7000},
{name: 'largeBar', xp: 18100},
{name: 'largeRubyStardust', xp: 14200}
]
const spells = [
{name: 'heal', xp: 25},
{name: 'poison', xp: 60},
{name: 'reflect', xp: 150},
{name: 'fire', xp: 180},
{name: 'freeze', xp: 250},
{name: 'ghostScan', xp: 300},
{name: 'invisibility', xp: 500}
]
pots.forEach(e=>{if(!e.name.includes('repel')){e.name += 'Potion'}})
const emoticons = {
slightly_smiling_face: ':)',
open_mouth: ':o',
scream: ':O',
smirk: ':]',
grinning: ':D',
stuck_out_tongue_winking_eye: ';P',
rage: ':@',
frowning: ':(',
kissing_heart: ':*',
wink: ';)',
pensive: ':/',
confounded: ':s',
flushed: ':|',
relaxed: ':$',
mask: ':x',
heart: '<3',
thumbsup: ':+1:',
thumbsdown: ':-1:',
sunglasses: 'B)',
}
const betterEmotes = {
FeelsBadMan: 'https://cdn.frankerfacez.com/emoticon/33355/1',
monkaS: 'https://cdn.frankerfacez.com/emoticon/130762/1',
Pepega: 'https://cdn.frankerfacez.com/emoticon/243789/1',
PepeHands: 'https://cdn.frankerfacez.com/emoticon/231552/1',
monkaW: 'https://cdn.frankerfacez.com/emoticon/214681/1',
FeelsGoodMan: 'https://cdn.frankerfacez.com/emoticon/109777/1',
peepoBlanket: 'https://cdn.frankerfacez.com/emoticon/262458/1',
Pog: 'https://cdn.frankerfacez.com/emoticon/301073/1',
NotLikeThis: 'https://static-cdn.jtvnw.net/emoticons/v1/58765/1.0',
NODDERS: 'https://cdn.betterttv.net/emote/5eadf40074046462f7687d0f/1x'
}
const betterEmotesKeys = Object.keys(betterEmotes)
const mainDarkColor = '#222831'
const mainLightColor = '#393e46'
const mainWhiteColor = '#eeeeee'
const mainOrangeColor = '#c99024'
const chatInput = document.getElementById('chat-area-input')
const chatView = document.getElementById('chat-area-view')
const chatArea = document.getElementById('chat-area')
const fightScreen = document.getElementById('navigation-right-combat-fighting')
const combatMap = document.getElementById('combat-map-div')
const game = document.getElementById('game')
const audio = new Audio('./sounds/success.wav')
const menuButtons = [{
id: 'pinging-button',
key:'pingingOn'},{
id: 'pm-pinging-button',
key:'pingPM'},{
id: 'set-words-button',
key:'words'},{
id: 'emoji-button',
key:'emoji'},{
/*id: 'chat-friendlist',
key:'friends'},{
id: 'twitchemotes-button',
key:'twitchEmotes'},{
id: 'chat-ignorelist',
key:'ignore'*/},{
id: 'emoji-send-button-settings',
key:'emojiButton'},{
id: 'chat-on-side',
key:'chatOnSide'},{
id: 'chat-on-bottom',
key:'chatOnBottom'},{
id: 'chat-in-combat',
key:'chatInCombat'},{
id: 'chat-color-settings',
key: 'color'},{
id: 'alternate-backgrounds',
key: 'alternateBackgrounds'},{
id: 'pause-autoscroll-onscroll',
key: 'pauseAutoscroll',}
]
var autoScroll = true
var scrolldelay
var playerIsMod = false
var chatSettings = {}
var lastPM = ''
var twitchEmotes = []
var emojiList = []
var allEmojis = []
var emojiIndex = 0
var chatIndex = true
var previousPlayerName
var previousElementWidth
var addedWidth = false
// wait for game to load
const chatCommands = [{
command: 'lol',
value: () => ''},{
command: '!level',
value: (word, lowercase, stats)=> stats !== 1 ? `:${lowercase}Skill: ${word} Level: ${stats.currentLevel} | Current XP: ${stats.currentXp} | XP needed for ${stats.askedLevel} level: ${stats.neededXp}` + (stats.sdNeeded ? ` | SD needed: ${stats.sdNeeded}` : '') : ''},{
command: '!gems',
value: () => (window.var_sapphireMined || 0) + '/' + (window.var_emeraldMined || 0) + '/' + (window.var_rubyMined || 0) + '/' + (window.var_diamondMined || 0) + '/' + (window.var_bloodDiamondMined || 0) + ' in ' + window.formatTime(window.var_playtime)},{
command: '!kc',
value: (word, lowercase)=> window[word + 'Monster'] ? word.replace(/([A-Z])/g, ' $1').trim() + ' Killed: ' + (window[`var_${lowercase}Kills`] || 0) : ''},{
command: '!heat',
value: () => `You will have a total of ${getHeat()} heat if you burn all of your logs.`},{
command: '!combatguide',
value: () => 'https://old.reddit.com/r/DiamondHunt/comments/hnls62/combat_strategy_masterpost_magnus/'},{
command: '!wiki',
value: () => 'https://diamondhunt3.fandom.com/wiki/DiamondHunt3_Wiki'},{
command: '!anwinity',
value: () => 'https://anwinity.com/dh3/'},
]
const startThing = () => {
if(window.var_username){
pogchamp()
}else{
setTimeout(startThing, 1000)
}
}
startThing()
// run all functions when game is loaded
function pogchamp(){
document.querySelector('#navigation-right-achievements-button').children[0].querySelector('div').textContent = 'Achi'
loadSettingsFromStorage()
addScripts()
createChatSettingsButton()
createEmojiButton()
createMainContainer()
createChatSettings('dialogue-extra-chat-settings', 'things-for-dh3')
createChatSettings('dialogue-set-words', 'things-for-dh3', 'words')
createChatSettings('dialogue-friendlist', 'things-for-dh3', 'friends')
createChatSettings('dialogue-ignorelist', 'things-for-dh3', 'ignore')
createChatSettings('dialogue-emoji', 'things-for-dh3', 'emoji')
createChatSettings('dialogue-color-settings', 'things-for-dh3', 'color')
updateLists('friend', '', 'load')
updateLists('ignore', '', 'load')
chatSettings.volume ? audio.volume = chatSettings.volume/10 : audio.volume = 1
chatSettings.fontSize ? chatArea.style.fontSize = (chatSettings.fontSize + 'pt') : chatArea.style.fontSize = '16pt'
darkMode()
window.var_chatTag === 'Moderator' ? playerIsMod = true : playerIsMod = false
// getTwitchEmotes()
createRightClickMenu()
createMenuButtons()
createMuteMenu()
window.setAutoScroll(!window.global_autoscrollChat)
document.getElementById('chat-autoscroll-button-check').src = 'images/check.png'
addStyle(`a{
color:cyan
}
a:visited{
color:darkcyan
}`)
chatPinging()
fightScreenObserver()
combatMapObserver()
chatOnTheSide()
chatOnTheBottom()
chatInput.addEventListener('keydown', (event) => {doCommand(event); window.chatInput(event)})
}
// chat input
function doCommand(event){
/*if (event.key === 'Tab' && lastPM !== '' && chatInput.value === ''){
chatInput.value = '/pm ' + lastPM + ' '
event.preventDefault()
}*/
if (!event.key || event.key === 'Enter'){
chatInput.value.split(' ').forEach((word, index) => {
if(word.startsWith('!') && word.length>4){
let object = chatCommands.filter(f=>word.startsWith(f.command))[0] || chatCommands[0]
let level = word.match(/[0-9]/g) !== null ? word.match(/[0-9]/g).join('') : 'next'
let item = level === 'next' ? word.substring(object.command.length) : word.substring(object.command.length, word.indexOf(level))
let lowercase = item.charAt(0).toLowerCase() + item.substring(1)
let uppercase = item.charAt(0).toUpperCase() + item.substring(1)
let stats = getStats(lowercase, level)
if (object.command === '!level'){
addCommandResult(stats, 1, uppercase)
chatInput.value = ''
if (autoScroll){
chatView.scrollTo(0, chatView.scrollHeight)
}
return
}
else if ( object.command === '!heat'){
chatInput.value = `/pm ${window.var_username.replace(/ /g,'_')} ` + chatInput.value.replace(word, object.value(item, lowercase, stats)) + (stats.itemsNeeded ? stats.itemsNeeded : '')
}else{
chatInput.value = chatInput.value.replace(word, object.value(item, lowercase, stats))
}
}
})
}
//window.chatInput()
}
// add custom style
function getStats(lowercase, level){
if (!window[`var_${lowercase}Xp`]){
return 1
}
let stats = {}
stats.bonusXp = !!(window.var_bonusXp) ? 1.1 : 1
stats.currentXp = window[`var_${lowercase}Xp`]
stats.currentLevel = window.getLevel(window[`var_${lowercase}Xp`])
if (level === 'next' || level <= stats.currentLevel){level = stats.currentLevel + 1}
//if (level > 100){level = 100}
stats.askedLevel = level
stats.neededXp = window.getXpNeeded(level) + 1 - window[`var_${lowercase}Xp`]
if (lowercase === 'crafting' || lowercase === 'mining'){
let sdCost = {none: 17, sapphire: 16, emerald: 15, ruby: 14, diamond: 12}
let gem = lowercase === 'crafting' ? getGem('StardustHammer') : getGem('StardustPickaxe')
stats.sdNeeded = Math.ceil((stats.neededXp / stats.bonusXp)) * sdCost[gem]
}
if (lowercase === 'crafting'){
let bodies = [150, 200, 1000]
stats.items = []
stats.itemsExtra = []
global_stardustToolsMap.stardustHammer.arrayItemsToConvertArray.forEach((item,index) => {
stats.items.push(Math.ceil(stats.neededXp / (global_stardustToolsMap.stardustHammer.arrayItemsConvetXpArray[index] * stats.bonusXp)))
})
bodies.forEach((xp, index)=>{
stats.itemsExtra.push(Math.ceil(stats.neededXp / (xp * stats.bonusXp)))
})
}else if (lowercase === 'mining'){
stats.items = []
global_stardustToolsMap.stardustPickaxe.arrayItemsToConvertArray.forEach((item,index)=> {
stats.items.push(Math.ceil(stats.neededXp / (global_stardustToolsMap.stardustPickaxe.arrayItemsConvetXpArray[index] * stats.bonusXp)))
})
}else if (lowercase === 'brewing'){
stats.items = []
pots.forEach(item => {
stats.items.push(Math.ceil(stats.neededXp / (item.xp * stats.bonusXp)))
})
}else if (lowercase === 'farming'){
stats.items = []
stats.totalXp = 0
stats.totalMaterial = 0
window.global_seedMap.forEach(item => {
stats.items.push(Math.ceil(stats.neededXp / (item.xp * stats.bonusXp)))
if (window[`var_${item.name}`]){
stats.totalXp += (parseInt(item.xp) * stats.bonusXp) * parseInt(window[`var_${item.name}`])
stats.totalMaterial += parseInt(item.bonemeal) * parseInt(window[`var_${item.name}`])
}
})
}else if (lowercase === 'magic'){
stats.items = []
stats.xpPerFight = 0
spells.forEach(item => {
if (window[`var_${item.name}`]){
stats.items.push(Math.ceil(stats.neededXp / Math.floor(item.xp * stats.bonusXp)))
stats.xpPerFight += (item.xp * stats.bonusXp)
}
})
}else if (lowercase === 'cooking'){
let oven = Object.keys(window).filter(oven => oven.includes('Oven') && oven.includes('var') && !oven.includes('Total') && !oven.includes('Bought')).filter(oven => window[oven] == 1)[0].substring(4)
let successRate = {bronzeOven: 0.5, ironOven: 0.6, silverOven: 0.7, goldOven: 0.8, promethiumOven: 0.9}
if (window.var_researcherCooking > 1){
successRate[oven] += (1 - successRate[oven])*0.25
}
if (window.var_researcherCooking > 2){
successRate[oven] += 0.0375
}
successRate[oven] = successRate[oven].toFixed(4)
stats.heatNeeded = Math.ceil((stats.neededXp / stats.bonusXp) / 30)
stats.expectedHeatNeeded = Math.ceil(stats.heatNeeded / successRate[oven])
}
return stats
}
function addCommandResult(stats, value, uppercase){
$(chatView).append(`<div id="levelCommand" style="border: 1px solid #eeeeee;background: #202040">
<div>
<span style="color: chocolate;margin-left: 5px">${uppercase} Level:</span>
<span style="color: #eeeeee;margin-left: 5px">${stats.currentLevel}</span>
</div>
<div>
<span style="color: chocolate;margin-left: 5px">Current XP:</span>
<span style="color: #eeeeee;margin-left: 5px">${window.formatNumber(stats.currentXp)}</span>
</div>
<div>
<span style="color: chocolate;margin-left: 5px">XP needed for ${stats.askedLevel} level:</span>
<span style="color: #eeeeee;margin-left: 5px">${window.formatNumber(stats.neededXp)}</span>
</div>
</div>`)
let lastElement = document.querySelectorAll('#levelCommand')[document.querySelectorAll('#levelCommand').length-1]
if (uppercase.toLowerCase() === 'crafting'){
$(lastElement).append(`
<div>
<span style="color: chocolate;margin-left: 5px">SD needed: </span>
<span style="color: #eeeeee;margin-left: 5px">${window.formatNumber(stats.sdNeeded)}</span>
</div>`)
levelItemsNeeded(lastElement, stats, 'crafting')
}else if (uppercase.toLowerCase() === 'mining'){
$(lastElement).append(`
<div>
<span style="color: chocolate;margin-left: 5px">SD needed: </span>
<span style="color: #eeeeee;margin-left: 5px">${window.formatNumber(stats.sdNeeded)}</span>
</div>`)
levelItemsNeeded(lastElement, stats, 'mining')
}else if (uppercase.toLowerCase() === 'brewing'){
levelItemsNeeded(lastElement, stats, 'brewing')
}else if (uppercase.toLowerCase() === 'farming'){
levelItemsNeeded(lastElement, stats, 'farming')
$(lastElement).append(`
<div>
<span style="color: chocolate;margin-left: 5px">Xp if you harvest all seeds: </span>
<span style="color: #eeeeee;margin-left: 5px">${window.formatNumber(stats.totalXp)}</span>
</div>
<div>
<span style="color: chocolate;margin-left: 5px">Bonemeal needed to plant all seeds: </span>
<span style="color: #eeeeee;margin-left: 5px">${window.formatNumber(stats.totalMaterial)}</span>
</div>`)
}else if (uppercase.toLowerCase() === 'magic'){
levelItemsNeeded(lastElement, stats, 'magic')
$(lastElement).append(`
<div>
<span style="color: chocolate;margin-left: 5px">Xp per fight: </span>
<span style="color: #eeeeee;margin-left: 5px">${window.formatNumber(stats.xpPerFight)}</span>
</div>`)
$(lastElement).append(`
<div>
<span style="color: chocolate;margin-left: 5px">Fights needed for level up: </span>
<span style="color: #eeeeee;margin-left: 5px">${window.formatNumber(Math.ceil(stats.neededXp / stats.xpPerFight))}</span>
</div>`)
}else if (uppercase.toLowerCase() === 'cooking'){
$(lastElement).append(`
<div>
<span style="color: chocolate;margin-left: 5px">Heat needed: </span>
<span style="color: #eeeeee;margin-left: 5px">${window.formatNumber(stats.heatNeeded)}</span>
</div>
<div>
<span style="color: chocolate;margin-left: 5px">Heat needed including burn rate: </span>
<span style="color: #eeeeee;margin-left: 5px">${window.formatNumber(stats.expectedHeatNeeded)}</span>
</div>
<div>
<span style="color: chocolate;margin-left: 5px">Current heat: </span>
<span style="color: #eeeeee;margin-left: 5px">${window.formatNumber(getHeat())}</span>
</div>
`)
}
}
function levelItemsNeeded(lastElement, stats, key){
let temp = []
let text = ''
let bodies = ['bearFurBody', 'polarBearFurBody', 'reaperBody']
switch (key){
case 'farming':
temp = [...window.global_seedMap]
text = 'Seeds needed to plant: '
break
case 'brewing':
temp = [...pots]
text = 'Pots needed to brew: '
break
case 'mining':
temp = window.global_stardustToolsMap.stardustPickaxe.arrayItemsToConvertArray.map(e=>{return {name: e}})
text = 'Ores needed: '
break
case 'crafting':
temp = [...window.global_stardustToolsMap.stardustHammer.arrayItemsToConvertArray.map(e=>{return {name: e}}), ...bodies]
text = 'Bars needed: '
break
case 'magic':
temp = [...spells]
text = 'Spells needed to cast: '
break
}
let wrapper = document.createElement('div')
wrapper.id = 'cmd-wrapper'
wrapper.style = 'display: flex; flex-direction: row; flex-wrap: wrap;'
lastElement.appendChild(wrapper)
$(wrapper).append(`<span style="color: chocolate;margin-left: 5px">${text} </span>`)
stats.items.forEach((item, index)=>{
let div = document.createElement('div')
div.style = 'display: flex; flex-direction: row; margin-left: 2px'
div.id = 'cmd-' + temp[index].name
wrapper.appendChild(div)
$(div).append(`
<img src=/images/${temp[index].name}.png style="height:1.2em;vertical-align:middle;margin-left: 2px"></img>
<span style="color: #eeeeee;margin-left: 2px">${window.formatNumber(item)},</span>
`)
if (index === stats.items.length -1){
div.children[1].textContent = div.children[1].textContent.slice(0, -1)
}
})
if (key == 'crafting'){
wrapper = document.createElement('div')
wrapper.id = 'cmd-wrapper-extra'
wrapper.style = 'display: flex; flex-direction: row; flex-wrap: wrap;'
lastElement.appendChild(wrapper)
$(wrapper).append(`<span style="color: chocolate;margin-left: 5px">Bodies: </span>`)
stats.itemsExtra.forEach((item, index)=>{
let div = document.createElement('div')
div.style = 'display: flex; flex-direction: row; margin-left: 2px'
div.id = 'cmd-' + temp[index].name
wrapper.appendChild(div)
$(div).append(`
<img src=/images/${bodies[index]}.png style="height:1.2em;vertical-align:middle;margin-left: 2px"></img>
<span style="color: #eeeeee;margin-left: 2px">${window.formatNumber(item)},</span>
`)
if (index === stats.itemsExtra.length -1){
div.children[1].textContent = div.children[1].textContent.slice(0, -1)
}
})
}
}
function getHeat(){
return (
parseInt(window.var_heat || 0) +
(window.var_logs*1 || 0) +
(window.var_oakLogs*2 || 0) +
(window.var_willowLogs*3 || 0) +
(window.var_bambooLogs*4 || 0) +
(window.var_mapleLogs*5 || 0) +
(window.var_lavaLogs*6 || 0) +
(window.var_pineLogs*7 || 0) +
(window.var_stardustLogs*8 || 0)
)
}
function addStyle(styleString) {
const style = document.createElement('style')
style.textContent = styleString;
document.head.append(style)
}
function getGem(tool) {
let result = null;
["diamond", "ruby", "emerald", "sapphire"].some(gem => {
if(window[`var_${gem}${tool}`]) {
result = gem
return true
}
});
return result || "none"
}
// get twitch emotes from api
/* function getTwitchEmotes(){
fetch('https://api.twitchemotes.com/api/v4/channels/0')
.then(response=> response.json())
.then(data=> {twitchEmotes = data.emotes})}
*/
// steal emojis from a website with emojis
function addScripts(){
let link = document.createElement('link')
link.id = 'color-picker'
link.rel = 'stylesheet'
// color picker css and script
link.href = 'https://cdn.jsdelivr.net/npm/[email protected]/dist/spectrum.min.css'
link.type = 'text/css'
document.getElementById('body').appendChild(link)
let script = document.createElement('script')
//script.id = 'spectrumscript'
script.src = "https://cdn.jsdelivr.net/npm/[email protected]/dist/spectrum.min.js"
document.getElementById('body').appendChild(script)
// emoji css and emoji list
link = document.createElement('link')
link.id = 'emoji-css'
link.rel = 'stylesheet'
link.href = "https://emoji-css.afeld.me/emoji.css"
document.getElementById('body').appendChild(link)
$.ajax({url: 'https://emoji-css.afeld.me/',success: (response)=>{
emojiList = response.split(' ')
.filter(item => item.includes('em-') && item.endsWith('"'))
.map(item => item.substring(3))
.map(item => item.slice(0,-1))
emojiList = emojiList
.filter(emoji => (!emoji.includes('flag') && !emoji.includes('male') && !emoji.includes('man') && !emoji.includes('arrow') && !emoji.includes('clock') && !emoji.includes('trian')))
//allEmojis = dhEmoji.concat(emojiList)
allEmojis = betterEmotesKeys.concat(dhEmoji, emojiList)
}})
}
// chat pinging
// style of pinged message
function ping(parentElement){
audio.play()
// background color, rgb, last value is opacity
parentElement.style.background = chatSettings.colors.pingColor
// color of text
parentElement.style.color = 'white'
}
function fightScreenObserver(){
const observer = new MutationObserver(messages=>{
if (fightScreen.style.display !== 'none'){
if(chatSettings.chatInCombat){
chatArea.style.display = 'none' ? chatArea.style.display = '' : null
}else{
game.style.width = '100%'
}
}else{
if (chatSettings.chatOnSide){
game.style.width !== '69%' ? game.style.width = '69%' : null
}
}
})
const config = { attributes: true }
observer.observe(fightScreen, config)
}
function combatMapObserver(){
const observer = new MutationObserver(messages=>{
console.log(combatMap.style.display)
if (combatMap.style.display !== 'none'){
chatArea.style.display = 'none'
}else{
chatArea.style.display = ''
}
})
const config = { attributes: true }
observer.observe(combatMap, config)
}
// pinging logic
function chatPinging(){
const observer = new MutationObserver(messages=>{
//console.log(messages)
messages.forEach((mutation,index)=>{
if (mutation.addedNodes.length === 1){
"use strict";
let spans = mutation.addedNodes[0].querySelectorAll('span')
// replace text with emoji for level command and break function, probably shouldnt be doing it here but w/e
if (spans[0].textContent.includes('Level:')){
if (autoScroll){
chatView.scrollTo(0, chatView.scrollHeight)
}
return console.log('Chat command')
}
// extract each element
let isFriend = false
let images = mutation.addedNodes[0].querySelectorAll('img') !== null ? mutation.addedNodes[0].querySelectorAll('img') : null
let nameElement = mutation.addedNodes[0].querySelectorAll('b')[0]
let messageElement = mutation.addedNodes[0].querySelectorAll('span')[mutation.addedNodes[0].querySelectorAll('span').length - 1]
let textElement = messageElement.childNodes[1]
let timeElement = spans[0]
let parentElement = spans[0].parentNode
let tagElement = parentElement.querySelector('[class*=chat-tag]') ? parentElement.querySelector('[class*=chat-tag]') : 'none'
// handling images
images.forEach(image => {
image.style.maxHeight = '1.2em'
image.style.width = 'auto'
if (image.src.includes('investor')) tagElement = 'Investor'
if (image.src.includes('smileIcon')){
isFriend = true
image.remove()
}
})
// analyze message
let message = analyzeMessage(nameElement, messageElement, images, parentElement, timeElement, tagElement)
// removing ignored message
/*if (message.isIgnored && !message.isPMsent){
parentElement.remove()
return console.log('Killed ignored message.')
}*/
if (chatIndex){
parentElement.id = 'odd'
}else{
parentElement.id = 'even'
}
chatIndex = !chatIndex
// removing pm command
if (message.playerName === window.var_username && !message.isPMsent && (message.content.includes('XP needed') || message.content.includes('You will have a total'))){
parentElement.remove()
return console.log('Killed command pm message.')
}
// dark mode settings
// setting ids for coloring
if (message.tag === 'none' || message.tag === 'Donor' || message.tag === 'Super Donor' || message.tag === 'Ultra Donor' || message.tag === 'Contributor'){
parentElement.id += 'notag'
}
message.tag !== 'none' && message.tag !== 'Investor' ? parentElement.id += tagElement.className : parentElement.id += 'notag'
message.tag === 'Investor' ? parentElement.id += message.tag : null
// resizing tags
if (message.tag !== 'Investor' && message.tag !== 'none'){
tagElement.style.display = 'inline-flex'
tagElement.style.height = '1.2em'
tagElement.style.verticalAlign = 'middle'
tagElement.style.alignItems = 'center'
tagElement.style.fontSize = 'small'
}
// some styling
/*nameElement.style.display = 'inline-block'
nameElement.style.marginRight = '4px'*/
messageElement.style.overflowWrap = 'anywhere'
timeElement.style.color = 'darkgrey'
parentElement.style.padding = '3px'
// coloring background of every other message
changeStyle('index', parentElement)
// coloring names/messages based on state
messageElement.style.color = chatSettings.colors.chatFontColor
if (chatSettings.alternateBackgrounds){
if (parentElement.id.includes('even')){
messageElement.style.color = chatSettings.colors.alternateFontColor
}
}
if (!message.isPM){
// color normal friend or normal user
isFriend ? nameElement.style.color = chatSettings.colors.friendColor : nameElement.style.color = chatSettings.colors.usernameColor
// check if you
if (message.playerName === window.var_username.replace(/ /g,'_')){
nameElement.style.color = chatSettings.colors.yourNameColor
}
// color messages based on tags
switch (message.tag){
case 'Dev':
messageElement.style.color = chatSettings.colors.devColor
nameElement.style.color = chatSettings.colors.devColor
break
case 'Moderator':
if (!isFriend){
if (chatSettings.alternateBackgrounds){
if (parentElement.id.includes('even')){
messageElement.style.color = chatSettings.colors.alternateFontColor
}else{
messageElement.style.color = chatSettings.colors.chatFontColor
}
}else{
messageElement.style.color = chatSettings.colors.chatFontColor
}
nameElement.style.color = chatSettings.colors.moderatorColor
}
break
case 'Server Message':
tagElement.style.verticalAlign = 'middle'
if (message.playerName === window.var_username){
audio.play()
parentElement.style.background = chatSettings.colors.pingColor
}
nameElement.style.color = chatSettings.colors.serverColor
break
case 'Financier':
messageElement.style.color = chatSettings.colors.financierColor
nameElement.style.color = chatSettings.colors.financierColor
break
case 'Investor':
messageElement.style.color = chatSettings.colors.investorColor
nameElement.style.color = chatSettings.colors.investorColor
break
}
// color pms
}else if(message.isPM && !message.isPMsent){
messageElement.style.color = chatSettings.colors.PMColor
}else{
messageElement.style.color = chatSettings.colors.PMColor
}
// ping
if(!message.isPM && chatSettings.pingingOn && !message.isIgnored){
// check if user has set any exactwords
if (chatSettings.exactWords.length>0){
message.words.forEach(messageWord => {
chatSettings.exactWords.forEach(exactWord => {
// check if a word matches predefined ping words
if(exactWord === messageWord.toLowerCase()){
ping(parentElement)
}
})
})
}
// check if user has set any matchwords
if(chatSettings.matchWords.length>0){
chatSettings.matchWords.forEach(matchWord => {
// check if a message contains any form of predefined words
message.content.toLowerCase().includes(matchWord) ? ping(parentElement) : null
})
}
// ping if message is a pm and user has pms on
}else if(message.isPM && !message.isPMsent && chatSettings.pingPM && !message.isIgnored){
ping(parentElement)
}
/*if (chatSettings.twitchEmotes){
message.words.forEach(word=>{
twitchEmotes.forEach(emote=>{
if (word === emote.code){
let prefix = parentElement[1].innerHTML.substring(0,parentElement[1].innerHTML.indexOf('</b>')+4)
let emoji = message.content.replace(word,`<img src="https://static-cdn.jtvnw.net/emoticons/v1/${emote.id}/1.0" style="vertical-align:middle;height: 32px" title="${word}"></img>`)
parentElement[1].innerHTML = prefix + emoji
}
})
})
}*/
// show emojis
if (chatSettings.emoji && message.tag != 'Server Message'){
let tempMessageHTML = ''
let emojiHTML = ''
for (let word of message.words){
if (word.includes('://')){
tempMessageHTML += `${convertStringToURL(word)} `
continue
}
if (word.startsWith(':') && word.endsWith(':')){
let text = word.substring(1, word.length-1)
// simplify some emojis
text === 'thinking' ? text = 'thinking_face' : null
text === 'cowboy' ? text = 'face_with_cowboy_hat' : null
text === 'facepalm' ? text = 'face_palm' : null
// check imported emojis
if (emojiList.includes(text)){
emojiHTML = emojiReplacer('css', text)
tempMessageHTML += `${emojiHTML} `
continue
}
// check dh emojis
if (dhEmoji.filter(emoji => emoji.includes(text)).length){
text = dhEmoji.filter(emoji => emoji.includes(text))[0]
emojiHTML = emojiReplacer('dh', text)
tempMessageHTML += `${emojiHTML} `
continue
}
}
// check emoticons :) :D :P
let name = Object.keys(emoticons).filter(short => emoticons[short] === word).length ? Object.keys(emoticons).filter(short => emoticons[short] === word) : null
name === 'thumbsup' ? name = '--1' : null
name === 'thumbsdown' ? name = '-1' : null
if (name !== null){
emojiHTML = emojiReplacer('css', name)
tempMessageHTML += `${emojiHTML} `
continue
}
// check bttv emotes
name = betterEmotesKeys.filter(emote => emote === word).length ? betterEmotesKeys.filter(emote => emote === word) : null
if (name !== null){
emojiHTML = emojiReplacer('bttv', name, betterEmotes[name])
tempMessageHTML += `${emojiHTML} `
continue
}
tempMessageHTML += `${word} `
}
if (!message.isPM){
messageElement.innerHTML = nameElement.outerHTML + tempMessageHTML
}else{
messageElement.innerHTML = `${message.PMprefix} ${tempMessageHTML}`
}
}
// add right click menu
//messageElement.innerHTML = messageElement.innerHTML.replace(/https?:\/\/(www\.)?[-a-zA-Z0-9@:%._\+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\b([-a-zA-Z0-9()@:%_\+.~#?&//=]*)/g, (m) => `<a href="${m}" target="_blank">${m}</a>`);
if (!message.isPM && message.tag != 'Server Message'){
let tempHTML = nameElement
mutation.addedNodes[0].querySelectorAll('b')[0].remove()
tempHTML.oncontextmenu = (event) => {event.preventDefault(); showChatMenu(event, message.playerName, isFriend)}
messageElement.prepend(tempHTML)
}else if (message.isPM && !message.isPMsent){
messageElement.oncontextmenu = (event) => {event.preventDefault(); showChatMenu(event, message.playerName, isFriend)}
}else {
messageElement.oncontextmenu = (event) => {event.preventDefault()}
}
//console.log(nameElement)
// scroll to the bottom
if (autoScroll){
chatView.scrollTo(0, chatView.scrollHeight)
}
}
})
})
// observer configs
const config = { childList: true }
observer.observe(chatView, config)
}
function emojiReplacer(key, name, src){
let img
switch (key){
// return html element with css emoji
case 'css':
img = `<i class="em em-${name}" style="height: 1.2em;" title="${name}"></i>`
break
// return html element with dh image
case 'dh':
img = `<img src="images/${name}.png" style="height: 1.2em; width:1.2em;vertical-align:middle" title="${name}">`
break
// return html element with bttv emote
case 'bttv':
img = `<img src=${src} style="height: 1.2em; width: 1.2em;vertical-align:middle">`
break
}
return img
}
// analyze message and its content
function analyzeMessage(nameElement, messageElement, img, parentElement, timeElement, tagElement){
let message = {}
message.time = timeElement.textContent.substring(6, timeElement.textContent.indexOf('[') + 1)
message.playerName = typeof nameElement !== 'undefined' ? nameElement.textContent.substring(0, nameElement.textContent.indexOf('(') - 1).replace(/ /g,'_') : null
message.playerLevel = typeof nameElement !== 'undefined' ? nameElement.textContent.substring(nameElement.textContent.indexOf('(') + 1, nameElement.textContent.indexOf(')')) : null
message.content = messageElement.textContent.substring(messageElement.textContent.indexOf(':') + 2).replace(/</g,'<').replace(/>/g,'>')
if (tagElement !== 'none'){
message.tag = tagElement === 'Investor' ? 'Investor' : tagElement.textContent
}else{
message.tag = 'none'
}
let msg = messageElement.textContent
message.words = message.content.split(' ').filter(word => word !== '')
if (msg.replace(' ','').startsWith('[')){
if (msg.replace(' ','').substring(1).startsWith('PM')){
message.isPM = true
message.isPMsent = false
message.playerName = msg.substring(msg.indexOf('m') + 2, msg.indexOf(']')).trim().replace(/ /g,'_')
lastPM = message.playerName
}else{
message.isPM = true
message.isPMsent = true
message.playerName = msg.substring(msg.indexOf('o') + 2, msg.indexOf(']')).trim().replace(/ /g,'_')
}
message.PMprefix = messageElement.textContent.substring(0, messageElement.textContent.indexOf(']') + 1)
message.words = messageElement.textContent.substring(messageElement.textContent.indexOf(']') + 1).split(' ').filter(char => !char == '')
}else{
message.isPM = false
}
//message.isFriend = chatSettings.friendList.includes(message.playerName) ? true : false
//message.isIgnored = chatSettings.ignoreList.includes(message.playerName) ? true : false
return message
}
// clicking buttons
function changeSettings(id, key, event){
let volume;
let div = document.getElementById(id)
let settingsWindow = document.getElementById('dialogue-extra-chat-settings')
switch (key){
case 'pingingOn':
case 'pingPM':
case 'chatInCombat':
case 'emoji':
case 'twitchEmotes':
case 'pauseAutoscroll':
chatSettings[key] ? chatSettings[key] = false : chatSettings[key] = true
break
case 'alternateBackgrounds':
chatSettings[key] ? chatSettings[key] = false : chatSettings[key] = true
document.querySelectorAll('#chat-area-view > div').forEach(div => { changeStyle('index', div) })
break
case 'chatOnSide':
if (!chatSettings.chatOnBottom){
chatSettings[key] ? chatSettings[key] = false : chatSettings[key] = true
}
break
case 'chatOnBottom':
if(!chatSettings.chatOnSide){
chatSettings[key] ? chatSettings[key] = false : chatSettings[key] = true
}
break
case 'words':
case 'color':
settingsWindow.style.display = 'none'
div.style.display = ''
break
case 'volume':
if (event === '+'){
chatSettings[key] < 10 ? chatSettings[key] += 1 : null
div.textContent = 'Volume: ' + chatSettings[key]
}else if (event === '-'){
chatSettings[key] > 0 ? chatSettings[key] -= 1 : null
div.textContent = 'Volume: ' + chatSettings[key]
}
audio.volume = chatSettings.volume/10
break
case 'fontSize':
if (event === '+'){
chatSettings[key] < 20 ? chatSettings[key] += 1 : null
div.textContent = 'Font Size: ' + chatSettings[key] + 'pt'
chatArea.style.fontSize = chatSettings[key] + 'pt'
}else if (event === '-'){
chatSettings[key] > 10 ? chatSettings[key] -= 1 : null
div.textContent = 'Font Size: ' + chatSettings[key] + 'pt'
chatArea.style.fontSize = chatSettings[key] + 'pt'
}
break
case 'pingColor':
case 'mainBackgroundColor':
case 'chatBackgroundColor':
case 'chatBackgroundColor2':
case 'usernameColor':
case 'serverColor':
case 'PMColor':
case 'friendColor':
case 'yourNameColor':
case 'devColor':
case 'financierColor':
case 'investorColor':
case 'moderatorColor':
case 'alternateFontColor':
case 'chatFontColor':
chatSettings.colors[key] = event
break
case 'friends':
case 'ignore':
settingsWindow.style.display = 'none'
div.style.display = 'flex'
break
case 'emojiButton':
chatSettings[key] ? chatSettings[key] = false : chatSettings[key] = true
chatSettings[key] ? div.style.display = '' : div.style.display = 'none'
break
}
styleButtons()
updateSettings()
}
// change styling depending on current state
function styleButtons(){
menuButtons.forEach(button => {
let div = document.getElementById(button.id)
switch (button.key){
case 'pingingOn':
case 'pingPM':
case 'emoji':
case 'twitchEmotes':
case 'emojiButton':
case 'chatOnSide':
case 'chatOnBottom':
case 'chatInCombat':
case 'alternateBackgrounds':
case 'pauseAutoscroll':
chatSettings[button.key] ? div.style.color = 'green' : div.style.color = 'red'
break
case 'words':
case 'friends':
case 'ignore':
case 'color':
div.style.color = mainWhiteColor
break
}})
}
function changeStyle(key, element){
let chatDivs = document.querySelectorAll('#chat-area-view > div')
let colors = Object.keys(chatSettings.colors)
switch(key){
case 'reset':
document.getElementById('dialogue-color-settings').querySelectorAll('input').forEach((input, index) => {
input.value = chatSettings.colors[colors[index]]
input.style.backgroundColor = chatSettings.colors[colors[index]]
})
//chatView.style.color = chatSettings.colors.chatFontColor
chatArea.style.background = chatSettings.colors.mainBackgroundColor
chatView.style.background = chatSettings.colors.chatBackgroundColor
chatDivs.forEach(div => {
let lastSpan = div.querySelectorAll('span')[div.querySelectorAll('span').length - 1]
div.id.includes('even') ? lastSpan.style.color = chatSettings.colors.alternateFontColor : null
div.id.includes('odd') ? lastSpan.style.color = chatSettings.colors.chatFontColor : null
div.id.includes('notag') ? div.querySelectorAll('b').forEach(b => {
let playername = b.textContent.substring(0, b.textContent.indexOf('(') - 1)
let isFriend = Object.keys(global_friendsAndIgnoreList).filter(x => global_friendsAndIgnoreList[x]=="friend").includes(playerName)
if (playername === window.var_username){
b.style.color = chatSettings.colors.yourNameColor
}else if (isFriend){
b.style.color = chatSettings.colors.friendColor
}else if (playername !== window.var_username && !isFriend){
b.style.color = chatSettings.colors.usernameColor
}
}) : null
if (div.id.includes('Dev')){
lastSpan.style.color = chatSettings.colors.devColor
div.querySelector('b').style.color = chatSettings.colors.devColor
}
if (div.id.includes('Financier')){
lastSpan.style.color = chatSettings.colors.financierColor
div.querySelector('b').style.color = chatSettings.colors.financierColor
}
if (div.id.includes('Investor')){
lastSpan.style.color = chatSettings.colors.investorColor
div.querySelector('b').style.color = chatSettings.colors.investorColor
}
div.id.includes('Moderator') ? div.querySelector('b').style.color = chatSettings.colors.moderatorColor : null
div.id.includes('yell') ? div.querySelector('b').style.color = chatSettings.colors.serverColor : null
div.textContent.includes('[PM') || div.textContent.includes('[Sent') ? lastSpan.style.color = chatSettings.colors.PMColor : null
})
break
case 'index':
if (chatSettings.alternateBackgrounds){
if (element.id.includes('even')){
element.style.background = chatSettings.colors.chatBackgroundColor2
}
}else{
element.style.background = chatSettings.colors.chatBackgroundColor
}
break
case 'chatFontColor':
case 'alternateFontColor':
chatDivs.forEach(div => {
let lastSpan = div.querySelectorAll('span')[div.querySelectorAll('span').length - 1]
console.log(((div.id.includes('notag') || div.id.includes('Moderator')) && !div.textContent.includes('[PM') && !div.textContent.includes('[Sent')))
if ((div.id.includes('notag') || div.id.includes('Moderator')) && !div.textContent.includes('[PM') && !div.textContent.includes('[Sent')){
if (chatSettings.alternateBackgrounds){
div.id.includes('even') ? lastSpan.style.color = chatSettings.colors.alternateFontColor : null
div.id.includes('odd') ? lastSpan.style.color = chatSettings.colors.chatFontColor : null
}else{
lastSpan.style.color = chatSettings.colors.chatFontColor
}
}
//div.id.includes('notag') ? div.querySelector('b').style.color = chatSettings.colors.usernameColor : null
})
break
case 'mainBackgroundColor':
chatArea.style.background = chatSettings.colors[key]
break
case 'chatBackgroundColor':
chatView.style.background = chatSettings.colors[key]
//document.querySelectorAll('#chat-area-view > div').forEach(div => {changeStyle('index', div)})
break
case 'chatBackgroundColor2':
chatDivs.forEach(div => { changeStyle('index', div) })
break
case 'serverColor':
chatDivs.forEach(div => { div.id.includes('yell') ? div.querySelector('b').style.color = chatSettings.colors[key] : null })
break
case 'PMColor':
chatDivs.forEach(div => { div.textContent.includes('[PM') || div.textContent.includes('[Sent') ? div.querySelectorAll('span')[div.querySelectorAll('span').length - 1].style.color = chatSettings.colors[key] : null })
break
case 'friendColor':
chatDivs.forEach(div => div.querySelectorAll('b').forEach(b => {
let playername = b.textContent.substring(0, b.textContent.indexOf('(') - 1)
if (Object.keys(global_friendsAndIgnoreList).filter(x => global_friendsAndIgnoreList[x]=="friend").includes(playername) && playername !== window.var_username){
b.style.color = chatSettings.colors[key]
}}))
break
case 'yourNameColor':
chatDivs.forEach(div => div.querySelectorAll('b').forEach(b => {
if (b.textContent.includes(window.var_username)){
b.style.color = chatSettings.colors[key]
}}))
break
case 'usernameColor':
chatDivs.forEach(div => div.querySelectorAll('b').forEach(b => {
let playername = b.textContent.substring(0, b.textContent.indexOf('(') - 1)
if (div.id.includes('notag') &&
chatSettings.friendList.includes(playername.replace(/ /g, '_')) && playername !== window.var_username){
b.style.color = chatSettings.colors[key]
}
}))
break
case 'serverColor':
chatDivs.forEach(div => div.querySelectorAll('b').forEach(b => {
if (div.id.includes('yell')){
b.style.color = chatSettings.colors[key]
}
}))
break
case 'moderatorColor':
chatDivs.forEach(div => div.querySelectorAll('b').forEach(b => {
if (div.id.includes('Moderator')){
b.style.color = chatSettings.colors[key]
}
}))
break
case 'devColor':
chatDivs.forEach(div => { if(div.id.includes('Dev')){
div.querySelectorAll('span')[div.querySelectorAll('span').length - 1].style.color = chatSettings.colors[key]
div.querySelector('b').style.color = chatSettings.colors[key]
}})
break
case 'financierColor':
chatDivs.forEach(div => { if(div.id.includes('Financier')){
div.querySelectorAll('span')[div.querySelectorAll('span').length - 1].style.color = chatSettings.colors[key]
div.querySelector('b').style.color = chatSettings.colors[key]
}})
break
case 'investorColor':
chatDivs.forEach(div => { if(div.id.includes('Investor')){
div.querySelectorAll('span')[div.querySelectorAll('span').length - 1].style.color = chatSettings.colors[key]
div.querySelector('b').style.color = chatSettings.colors[key]
}})
break
}
}
// add words from inputs to settings
function addWords(id, key){
event.preventDefault()
let input = document.getElementById(id)
let words = input.value.replace(/\s/g, '').split(',')
words.forEach((word, index) => {
if (word == ''){
words.splice(index,1)}
})
switch (key){
case 'exact':
chatSettings.exactWords = words
break
case 'match':
chatSettings.matchWords = words
break
}
updateSettings()
}
// add friend to storage
function addFriendIgnore(type, key, name){
let newest
switch (type){
case 'friend':
if (!key){
newest = document.querySelectorAll('#dialogue-friendlist > input')[0].value.trim().replace(/ /g,'_')
document.querySelectorAll('#dialogue-friendlist > input')[0].value = ''
}else{
newest = name
}
if(!chatSettings.friendList.includes(newest)){
chatSettings.friendList.push(newest)
updateLists('friend', newest, 'add')
changeStyle('friendColor')
}
break
case 'ignore':
if (!key){
newest = document.querySelectorAll('#dialogue-ignorelist > input')[0].value.trim().replace(/ /g,'_')
document.querySelectorAll('#dialogue-ignorelist > input')[0].value = ''
}else{
newest = name
}
if(!chatSettings.ignoreList.includes(newest)){
chatSettings.ignoreList.push(newest)
updateLists('ignore', newest, 'add')
}
break
}
updateSettings()
}
// add friend to friendlist
function updateLists(type, name, key){
switch (type){
case 'friend':
if (key == 'add'){
createListDiv(name, 'friend')
}else if(key == 'remove'){
document.getElementById('friend-' + name).remove()
}else{
chatSettings.friendList.forEach(friend => {
createListDiv(friend, 'friend')
})
}
break
case 'ignore':
if (key == 'add'){
createListDiv(name, 'ignore')
}else if(key == 'remove'){
document.getElementById('ignored-' + name).remove()
}else{
chatSettings.ignoreList.forEach(ignored => {
createListDiv(ignored, 'ignore')
})
}
break
}
}
function removeFromList(id, key){
let name = id
switch (key){
case 'friend':
chatSettings.friendList.forEach((friend, index) => {
friend === name ? chatSettings.friendList.splice(index, 1) : null
})
updateLists('friend', id, 'remove')
updateSettings()
changeStyle('usernameColor')
break
case 'ignore':
chatSettings.ignoreList.forEach((ignored, index) => {
ignored === name ? chatSettings.ignoreList.splice(index, 1) : null
})
updateLists('ignore', id, 'remove')
updateSettings()
break
}
}
// store values in localstorage
function loadSettingsFromStorage(key){
if (localStorage.getItem('chat-extra-settings') == null || key === 'reset'){
chatSettings = {
pingingOn: false,
pingPM: false,
volume: 1,
exactWords: [var_username, '@' + var_username],
matchWords: [],
friendList: [],
ignoreList: [],
emoji: true,
twitchEmotes: false,
emojiButton: false,
chatOnSide: false,
chatOnBottom: false,
chatInCombat: false,
alternateBackgrounds: false,
pauseAutoscroll: false,
fontSize: 16,
colors: {pingColor: 'rgba(255, 0, 0, 0.3)', chatFontColor: '#eeeeee', mainBackgroundColor: mainDarkColor, chatBackgroundColor: mainLightColor,
chatBackgroundColor2: '#32363d', alternateFontColor: '#eeeeee', usernameColor: mainOrangeColor, serverColor: '#C04238',
PMColor: '#68d140', friendColor: '#38f9b5', yourNameColor: '#00ffff', devColor: '#f5f215', financierColor: '#3e9dc0', investorColor: '#cc66ff', moderatorColor: '#189531'}
}
localStorage.setItem('chat-extra-settings',JSON.stringify(chatSettings))
}else{
chatSettings = JSON.parse(localStorage.getItem('chat-extra-settings'))
}
let set = ['emoji','twitchEmotes','ignoreList','emojiButton','chatOnSide','chatInCombat','chatOnBottom','alternateBackgrounds','pauseAutoscroll']
set.forEach(setting => {
if (chatSettings[setting] === undefined){
chatSettings[setting] = false
localStorage.setItem('chat-extra-settings',JSON.stringify(chatSettings))
}
})
if (chatSettings.ignoreList === undefined){
chatSettings.ignoreList = []
localStorage.setItem('chat-extra-settings',JSON.stringify(chatSettings))
}
// default colors
if (chatSettings.colors === undefined || Object.keys(chatSettings.colors).length !== 15 || key === 'resetcolors'){
chatSettings.colors = {pingColor: 'rgba(255, 0, 0, 0.3)', chatFontColor: mainWhiteColor, mainBackgroundColor: mainDarkColor, chatBackgroundColor: mainLightColor,
chatBackgroundColor2: '#32363d', alternateFontColor: mainWhiteColor, usernameColor: mainOrangeColor, serverColor: '#C04238',
PMColor: '#68d140', friendColor: '#38f9b5', yourNameColor: '#00ffff', devColor: '#f5f215', financierColor: '#3e9dc0', investorColor: '#cc66ff', moderatorColor: '#189531' }
localStorage.setItem('chat-extra-settings',JSON.stringify(chatSettings))
}
if (chatSettings.fontSize === undefined){
chatSettings.fontSize = 16
localStorage.setItem('chat-extra-settings',JSON.stringify(chatSettings))
}
if (!Number.isInteger(chatSettings.volume)){
chatSettings.volume = 1
localStorage.setItem('chat-extra-settings',JSON.stringify(chatSettings))
}
if (key === 'reset'){
document.querySelectorAll('#friend-list > div').forEach(e=>e.remove())
document.querySelectorAll('#ignore-list > div').forEach(e=>e.remove())
}
}
function openChatSettings(event,id){
let offsetTop
let offsetLeft
chatSettings.chatOnSide ? offsetTop = 50 : offsetTop = 285
chatSettings.chatOnSide ? offsetLeft = 800 : offsetLeft = 254
if (document.getElementById(id).style.display == 'none'){
document.getElementById(id).style.display = 'flex'
document.getElementById(id).style.top = (event.pageY-offsetTop) + 'px'
document.getElementById(id).style.left = (event.pageX-offsetLeft)+ 'px'
document.getElementById('dialogue-color-settings').style.top = (event.pageY-offsetTop) + 'px'
document.getElementById('dialogue-color-settings').style.left = (event.pageX-offsetLeft)+ 'px'
document.getElementById('dialogue-set-words').style.top = (event.pageY-offsetTop) + 'px'
document.getElementById('dialogue-set-words').style.left = (event.pageX-offsetLeft)+ 'px'
document.getElementById('dialogue-friendlist').style.top = (event.pageY-offsetTop) + 'px'
document.getElementById('dialogue-friendlist').style.left = (event.pageX-offsetLeft)+ 'px'
document.getElementById('dialogue-ignorelist').style.top = (event.pageY-offsetTop) + 'px'
document.getElementById('dialogue-ignorelist').style.left = (event.pageX-offsetLeft)+ 'px'
document.getElementById('dialogue-emoji').style.top = (event.pageY-485) + 'px'
document.getElementById('dialogue-emoji').style.left = (event.pageX-offsetLeft)+ 'px'
}
}
function backButton(ID, parentID){
document.getElementById(parentID).style.display = 'flex'
document.getElementById(ID).style.display = 'none'
}
// update localstorage with new values
function updateSettings(){
localStorage.setItem('chat-extra-settings', JSON.stringify(chatSettings))
}
// dark mode
function darkMode(){
chatArea.style.color = mainWhiteColor
chatArea.style.background = chatSettings.colors.mainBackgroundColor
chatArea.style.fontSize = chatSettings.fontSize + 'pt'
chatInput.style.background = mainLightColor
chatInput.style.color = mainWhiteColor
chatInput.style.padding = '5px'
chatInput.style.border = '1px solid ' + mainOrangeColor
chatView.style.background = chatSettings.colors.chatBackgroundColor
chatView.style.color = chatSettings.colors.chatFontColor
chatView.style.marginTop = '5px'
document.getElementById('chat-autoscroll-button-check').style.height = '0.8em'
document.getElementById('chat-autoscroll-button-check').style.width = '0.8em'
document.querySelectorAll('.custom-chat-button').forEach((button ,index)=>{
button.style.border = '1px solid ' + mainOrangeColor
button.style.fontSize = '1vw'
button.style.display = 'inline-flex'
button.style.justifyContent = 'center'
button.style.alignItems = 'center'
button.style.height = '2vh'
button.style.padding = '8px'
if (index < 2){
button.style.background = mainOrangeColor
}
if (index > 1){
button.style.width = '5vw'
button.onmouseover = (event) => {
if (!event.target.src){
event.target.style.background = mainOrangeColor
event.target.style.color = 'black'
}
}
button.onmouseleave = (event) => {
if (!event.target.src){
event.target.style.background = 'none'
event.target.style.color = mainWhiteColor
}
}
}
if (index === 2){
document.querySelectorAll('.custom-chat-button')[2].setAttribute('onclick','')
button.onclick = () => {
autoScroll = !autoScroll
if (autoScroll){
document.getElementById('chat-autoscroll-button-check').src = 'images/check.png'
}else{
document.getElementById('chat-autoscroll-button-check').src = 'images/x.png'
}
}
}
})
document.querySelectorAll('.chat-area-send-button').forEach(button => {
button.style.padding = "8px"
button.style.background = mainLightColor
button.style.color = mainWhiteColor
button.style.border = '1px solid ' + mainOrangeColor
button.value = button.value.charAt(0).toUpperCase() + button.value.slice(1)
})
document.querySelector('.chat-area-send-button').setAttribute('onclick','')
document.querySelector('.chat-area-send-button').onclick = ()=> {doCommand(); window.chatSend()}
chatInput.setAttribute('onkeydown','')
chatView.onscroll = ()=>{
if (chatSettings.pauseAutoscroll){
if (autoScroll && chatView.scrollHeight != chatView.scrollTop + chatView.offsetHeight - 2){
autoScroll = false
document.getElementById('chat-autoscroll-button-check').src = 'images/x.png'
}else{
if (chatView.scrollHeight == chatView.scrollTop + chatView.offsetHeight - 2){
autoScroll = true
document.getElementById('chat-autoscroll-button-check').src = 'images/check.png'
}
}
}
}
}
function showChatMenu(event, playerName, isFriend){
let offsetTop, offsetLeft
chatSettings.chatOnSide ? offsetTop = 0 : offsetTop = 300
chatSettings.chatOnSide ? offsetLeft = '50vw' : offsetLeft = 400
event.pageY > (window.innerHeight - 100) ? offsetTop = 100 : offsetTop = 0
if (document.getElementById('chat-rightclick-menu').style.display === 'none' && playerName !== window.var_username){
document.getElementById('chat-rightclick-menu').style.top = (event.pageY - offsetTop) + 'px'
document.getElementById('chat-rightclick-menu').style.left = (event.pageX-10)+ 'px'
document.getElementById('chat-rightclick-menu-mute-settings').style.top = (event.pageY + offsetTop) + 'px'
document.getElementById('chat-rightclick-menu-mute-settings').style.left = offsetLeft
document.getElementById('chat-rightclick-menu').style.display = 'flex'
document.getElementById('chat-rightclick-menu').className = playerName
if (isFriend){
let elem = document.getElementById('chat-rightclick-menu-add friend')
elem.textContent = 'Remove friend'
elem.onclick = () => changeMenu('remove friend')
}
}
}
function changeMenu(key){
let playerName = document.getElementById('chat-rightclick-menu').className
if (!playerName.startsWith('guest') && key == 'ignore'){
playerName = playerName.replace(/_/g,' ')
}
//if (Object.keys(global_friendsAndIgnoreList).filter(x => global_friendsAndIgnoreList[x]=="friend").includes(playerName.replace(/_/g,' '))) key = 'remove friend'
switch(key){
case 'PM':
document.getElementById('chat-rightclick-menu').style.display = 'none'
chatInput.value = '/pm ' + playerName + ' '
chatInput.focus()
break
case 'add friend':
addFriend(playerName.replace(/_/g,' '))
break
case 'remove friend':
sendBytes(`REMOVE_FRIEND=${playerName.replace(/_/g,' ')}`)
break
case 'ignore':
addIgnore(playerName)
break
case 'mute':
if(window.ModMod) {
window.ModMod.prefillMute(playerName, true, true);
}
else {
document.getElementById('chat-rightclick-menu').style.display = 'none'
document.getElementById('chat-rightclick-menu-mute-settings').style.display = 'flex'
}
break
case 'ban':
document.getElementById('chat-rightclick-menu').style.display = 'none'
chatInput.value = '/smute ' + playerName + ' -1 0 '
break
case 'who is':
if(window.ModMod) {
window.ModMod.whoIs(playerName, true);
}else{
chatInput.value = '/whois ' + playerName.replace(/_/g,' ')
}
break
case 'profile':
window.open(`https://dh3.diamondhunt.co/hiscores/search.php?username=${playerName.replace(/_/g, ' ')}`)
break
case 'compare':
window.open(`https://anwinity.com/dh3/compare/#p1=${window.var_username}&p2=${playerName.replace(/_/g,' ')}`)
break
}
}
function mutePlayer(configs){
let playerName = document.getElementById('chat-rightclick-menu').className
chatInput.value = '/smute ' + playerName + ' '
configs.forEach(config=>{
chatInput.value += config.value + ' '
})
}
function inputClear(){
document.getElementById('chat-rightclick-menu-mute-settings').style.display = 'none'
document.querySelectorAll('#chat-rightclick-menu-mute-sub > input').forEach(input=>{input.value = ''})
}
function lookForEmoji(){
let input = document.getElementById('search-emoji').value
let buttons = document.querySelectorAll('#emoji-list > button')
buttons.forEach(button=>{
if (button.id.includes(input)){
button.style.display = ''
}else{
button.style.display = 'none'
}
})
if (input===''){emojiIndex++;changeEmojiWindow(false)}
}
function changeEmojiWindow(key){
let buttons = document.querySelectorAll('#emoji-list > button')
if (key){
if (emojiIndex < (buttons.length / 100)-1){
emojiIndex++
document.querySelectorAll('#emoji-list > button:not([style*="display: none"])').forEach(e=>{e.style.display = 'none'})
let temp = emojiIndex*100
for (let i = temp; i < (temp + 100); i++){
i < buttons.length ? buttons[i].style.display = '' : null
}
}
}else{
if(emojiIndex>0){
emojiIndex--
document.querySelectorAll('#emoji-list > button:not([style*="display: none"])').forEach(e=>{e.style.display = 'none'})
let temp = emojiIndex*10
for (let i = temp; i < (temp + 100); i++){
i < buttons.length ? buttons[i].style.display = '' : null
}
}
}
}
function chatOnTheSide(){
if (!chatSettings.chatOnBottom){
if (chatSettings.chatOnSide){
game.style.width = '69%'
chatArea.style.position = 'fixed'
chatArea.style.top = '5%'
chatArea.style.right = '0'
chatArea.style.width = '30%'
chatArea.style.height = '100vh'
chatView.style.height = '77vh'
chatInput.style.width = '100%'
document.getElementById('extra-chat-settings').innerHTML = '<img src="https://img.icons8.com/cotton/64/000000/settings--v1.png" style="height: 4vh"/>'
document.getElementById('extra-chat-settings').style.width = '1vw'
document.getElementById('extra-chat-settings').style.border = 'none'
document.querySelectorAll('.chat-area-send-button').forEach(button => {button.style.marginTop = '5px'})
document.querySelectorAll('.custom-chat-button')[0].style.display = 'none'
document.querySelectorAll('.custom-chat-button')[1].style.display = 'none'
document.querySelectorAll('.tree-section').forEach(section => {section.style.height = '300px'})
document.querySelectorAll('.tree-section > img').forEach(section => {section.style.height = '200px'})
document.querySelectorAll('.plot-section').forEach(section => {section.style.height = '300px'})
document.querySelectorAll('.plot-section > img').forEach(section => {section.style.height = '200px'})
document.querySelectorAll('[id*=plot-section-shiny]').forEach(section => {section.style.width = '200px'})
document.querySelector('#navigation-right-skills > a').style.right = '30vw'
//document.querySelectorAll('.not-table-top-main-skills-item').forEach(e=>e.style.minWidth = '15%')
//document.querySelectorAll('#table-top-main-items > tbody')[0].childNodes[0].childNodes[5].style.width = '30%'
}else{
game.style.width = '100%'
chatArea.style.position = ''
chatArea.style.top = ''
chatArea.style.right = ''
chatArea.style.width = ''
chatArea.style.height = ''
chatView.style.height = '300px'
chatInput.style.width = ''
document.getElementById('extra-chat-settings').style.border = '1px solid ' + mainOrangeColor
document.getElementById('extra-chat-settings').style.width = '6vw'
document.getElementById('extra-chat-settings').innerHTML = 'Settings'
document.querySelectorAll('.chat-area-send-button').forEach(button => {button.style.marginTop = ''})
document.querySelectorAll('.custom-chat-button')[0].style.display = ''
document.querySelectorAll('.custom-chat-button')[1].style.display = ''
document.querySelectorAll('.tree-section').forEach(section => {section.style.height = '350px'})
document.querySelectorAll('.tree-section > img').forEach(section => {section.style.height = '250px'})
document.querySelectorAll('.plot-section').forEach(section => {section.style.height = '350px'})
document.querySelectorAll('.plot-section > img').forEach(section => {section.style.height = '250px'})
document.querySelectorAll('[id*=plot-section-shiny]').forEach(section => {section.style.width = '250px'})
document.querySelector('#navigation-right-skills > a').style.right = '10px'
//document.querySelectorAll('.not-table-top-main-skills-item').forEach(e=>e.style.minWidth = '10%')
//document.querySelectorAll('#table-top-main-items > tbody')[0].childNodes[0].childNodes[5].style.width = '25%'
}
}
}
function chatOnTheBottom(){
if (!chatSettings.chatOnSide){
if (chatSettings.chatOnBottom){
chatArea.style.position = 'sticky'
chatArea.style.bottom = '0'
chatArea.style.zIndex = '1000'
}else{
chatArea.style.position = ''
chatArea.style.bottom = ''
}
}
}
// CREATING HTML ELEMENTS
// create main element in body
function createMainContainer(){
let div = document.createElement('div')
div.id = 'things-for-dh3'
document.getElementById('body').appendChild(div)
// $(div).insertBefore(document.querySelector('body > link'))
}
//create button in chat window
function createChatSettings(ID,parentID,key){
let div = document.createElement("div")
let id = ID
div.id = ID
div.style = `background: ${mainLightColor}; border: 5px solid ${mainDarkColor}; border-radius: 10px; height: 200px; width: 400px; padding-bottom: 50px; display: none; flex-direction: row; flex-wrap: wrap; font-family: sans-serif; justify-content: center; position: absolute; z-index: 1000`
// main menu
if (!key){
div.style.height = '400px'
let wrapper = document.createElement("div")
wrapper.style = 'display: flex; flex-direction: row; justify-content: center; height: 300px; width: 400px; margin-top: 20px;'
let leftDiv = document.createElement("div")
wrapper.style.width = '200px'
let rightDiv = document.createElement("div")
wrapper.style.width = '200px'
let button = addButtonToSettings('pinging-button', 'Word Pinging', 'pingingOn', () => changeSettings('pinging-button', 'pingingOn', event))
leftDiv.appendChild(button)
button = addButtonToSettings('pm-pinging-button', 'PM Pinging', 'pingPM', () => changeSettings('pm-pinging-button' , 'pingPM'))
leftDiv.appendChild(button)
/*button = addButtonToSettings('twitchemotes-button','Twitch Emotes','twitchEmotes',()=>changeSettings('twitchemotes-button','twitchEmotes'))
leftDiv.appendChild(button)*/
button = addButtonToSettings('emoji-button', 'Display Emoji', 'emoji', () => changeSettings('emoji-button', 'emoji'))
leftDiv.appendChild(button)
button = addButtonToSettings('emoji-send-button-settings', 'Emoji Button', 'emojiButton', () => changeSettings('emoji-send-button', 'emojiButton'))
leftDiv.appendChild(button)
button = addButtonToSettings('chat-on-side', 'Side Chat', 'chatOnSide', () => {changeSettings('chat-on-side', 'chatOnSide'); chatOnTheSide()})
leftDiv.appendChild(button)
button = addButtonToSettings('chat-on-bottom', 'Sticky chat', 'chatOnBottom', () => {changeSettings('chat-on-bottom', 'chatOnBottom'); chatOnTheBottom()})
leftDiv.appendChild(button)
button = addButtonToSettings('chat-in-combat', 'Chat in combat', 'chatInCombat', () => {changeSettings('chat-in-combat', 'chatInCombat')})
leftDiv.appendChild(button)
button = addButtonToSettings('alternate-backgrounds', 'Alternate backgrounds', 'alternateBackgrounds', () => {changeSettings('alternate-backgrounds', 'alternateBackgrounds')})
leftDiv.appendChild(button)
button = addButtonToSettings('pause-autoscroll-onscroll', 'Pause Autoscroll on scroll', 'pauseAutoscroll', () => {changeSettings('pause-autoscroll-onscroll', 'pauseAutoscroll')})
leftDiv.appendChild(button)
button = createAdjustableElements('volume')
rightDiv.appendChild(button)
button = createAdjustableElements('fontSize')
rightDiv.appendChild(button)
button = addButtonToSettings('set-words-button', 'Set words', 'words', () => changeSettings('dialogue-set-words', 'words'))
rightDiv.appendChild(button)
//button = addButtonToSettings('chat-friendlist', 'Friend List', 'friends', () => changeSettings('dialogue-friendlist', 'friends'))
//rightDiv.appendChild(button)
//button = addButtonToSettings('chat-ignorelist', 'Ignore List', 'ignore', () => changeSettings('dialogue-ignorelist', 'ignore'))
//rightDiv.appendChild(button)
button = addButtonToSettings('chat-color-settings', 'Colors', 'color', () => changeSettings('dialogue-color-settings', 'color'))
rightDiv.appendChild(button)
wrapper.appendChild(leftDiv)
wrapper.appendChild(rightDiv)
div.appendChild(wrapper)
// reset to default button
let resetButton = document.createElement("div")
resetButton.textContent = 'RESET EVERYTHING'
resetButton.style = 'cursor: pointer; position: absolute; top: 90%; left: 70%; width: 110px; color: red; background: black; border: 1px solid white; border-radius: 5px;'
resetButton.onclick = () => {
loadSettingsFromStorage('reset')
styleButtons()
changeStyle('reset')
chatOnTheSide()
chatView.style.fontSize = chatSettings.fontSize + 'pt'
}
div.appendChild(resetButton)
// words menu
}else if (key === 'words'){
let divChild = addForms('exact-words','Ping exactly those words:')
div.appendChild(divChild)
divChild = addForms('match-words','Ping any form of chosen words:')
div.appendChild(divChild)
//back button
let backDiv = document.createElement("div")
backDiv.onclick = () => {backButton('dialogue-set-words','dialogue-extra-chat-settings')}
backDiv.className = "dialogue-button"
backDiv.appendChild(document.createTextNode("Back"))
backDiv.style = `cursor: pointer; position: absolute; top: 80%; left: 240px; background: ${mainDarkColor}; border: 1px solid ${mainOrangeColor}; color: ${mainWhiteColor}`
div.appendChild(backDiv)
// friends menu
}else if (key === 'friends'){
// inputs for friends
div.style.justifyContent = 'center'
div.style.margin = '0'
let input = createInput('friendlist-name')
div.appendChild(input)
let button = document.createElement("button")
button.textContent = 'Add'
button.style.height = '36px'
button.onclick = () => {addFriendIgnore('friend')}
div.appendChild(button)
let divChild = document.createElement('div')
divChild.id = 'friend-list'
divChild.style = 'height: 100px; width: 300px; margin-top: 5px; overflow-y: auto; display: flex; flex-wrap: wrap;'
div.appendChild(divChild)
//back button
let backDiv = document.createElement("div")
backDiv.onclick = () => {backButton('dialogue-friendlist','dialogue-extra-chat-settings')}
backDiv.className = "dialogue-button"
backDiv.appendChild(document.createTextNode("Back"))
backDiv.style = `cursor: pointer; position: absolute; top: 80%; left: 240px; background: ${mainDarkColor}; border: 1px solid ${mainOrangeColor}; color: ${mainWhiteColor}`
div.appendChild(backDiv)
}else if (key === 'ignore'){
// inputs for ignored
div.style.justifyContent = 'center'
div.style.margin = '0'
let input = createInput('ignorelist-name')
div.appendChild(input)
let button = document.createElement("button")
button.textContent = 'Add'
button.style.height = '36px'
button.onclick = () => {addFriendIgnore('ignore')}
div.appendChild(button)
let divChild = document.createElement('div')
divChild.id = 'ignore-list'
divChild.style = 'height: 100px; width: 300px; margin-top: 5px; overflow-y: auto; display: flex; flex-wrap: wrap;'
div.appendChild(divChild)
//back button
let backDiv = document.createElement("div")
backDiv.onclick = () => {backButton('dialogue-ignorelist','dialogue-extra-chat-settings')}
backDiv.className = "dialogue-button"
backDiv.appendChild(document.createTextNode("Back"))
backDiv.style = `cursor: pointer; position: absolute; top: 80%; left: 240px; background: ${mainDarkColor}; border: 1px solid ${mainOrangeColor}; color: ${mainWhiteColor}`
div.appendChild(backDiv)
}else if (key === 'emoji'){
div.style.justifyContent = 'center'
div.style.margin = '0'
div.style.height = '400px'
let wrapper = document.createElement('div')
wrapper.style = 'display: flex; flex-direction: row; margin-top: 20px;'
let button = document.createElement('button')
button.textContent = '<'
button.style = `font-size: 26px; color: ${mainWhiteColor}; background: ${mainDarkColor}; border: 1px solid ${mainOrangeColor}; display: flex; align-items: center; height: 36px;`
button.onclick = () => {changeEmojiWindow(false)}
wrapper.appendChild(button)
let input = document.createElement('input')
input.id = 'search-emoji'
input.style = `border: 1px solid ${mainOrangeColor}; height: 36px; margin: 0 5px 0 5px;`
input.onkeyup = () => {lookForEmoji()}
wrapper.appendChild(input)
button = document.createElement('button')
button.textContent = '>'
button.style = `font-size: 26px; color: ${mainWhiteColor}; background: ${mainDarkColor}; border: 1px solid ${mainOrangeColor}; display: flex; align-items: center; height: 36px;`
button.onclick = () => {changeEmojiWindow(true)}
wrapper.appendChild(button)
div.appendChild(wrapper)
let divChild = document.createElement('div')
divChild.id = 'emoji-list'
divChild.style = 'height: 350px; width: 400px; margin-top: 5px; overflow-y: auto; display: flex; align-content: baseline; flex-wrap: wrap;'
function addEmojiToDialogue(){
if (allEmojis.length > (dhEmoji.length + betterEmotesKeys.length)){
allEmojis.forEach((emoji, index) => {
let button = document.createElement("button")
if (index < betterEmotesKeys.length){
button.innerHTML = `<img src="${betterEmotes[emoji]}" style="height:28px; width:auto;vertical-align:middle" title="${emoji}">`
}
else if (index >= betterEmotesKeys.length && index < (dhEmoji.length + betterEmotesKeys.length)){
button.innerHTML = `<img src="images/${emoji}.png" style="height:28px; width:auto;vertical-align:middle" title="${emoji}">`
}else{
button.innerHTML = `<i class="em em-${emoji}" style="height:28px;" title="${emoji}"></i>`
}
button.id = emoji
button.style.background = mainLightColor
button.style.border = 'none'
if (index < betterEmotesKeys.length){
button.onclick = () => {chatInput.value += emoji}
}else{
button.onclick = () => {chatInput.value += ' :' + emoji + ': '}
}
if (index > 100){
button.style.display = 'none'
}
divChild.appendChild(button)
})
}else{
setTimeout(addEmojiToDialogue, 1000)
}
}
addEmojiToDialogue()
div.appendChild(divChild)
}else if (key === 'color'){
div.style.height = '400px'
let divWrapper = document.createElement('div')
divWrapper.style = 'height: 350px; margin-top: 10px; overflow-y: auto;'
divWrapper.id = 'colorwrapper'
let divChild = addForms('pingColor', 'Ping color: ')
divWrapper.appendChild(divChild)
divChild = addForms('chatFontColor', 'Chat font color: ')
divWrapper.appendChild(divChild)
divChild = addForms('mainBackgroundColor', 'Outter background: ')
divWrapper.appendChild(divChild)
divChild = addForms('chatBackgroundColor', 'Chat background: ')
divWrapper.appendChild(divChild)
divChild = addForms('chatBackgroundColor2', 'Alternate background: ')
divWrapper.appendChild(divChild)
divChild = addForms('alternateFontColor', 'Alternate font color: ')
divWrapper.appendChild(divChild)
divChild = addForms('usernameColor', 'Username color: ')
divWrapper.appendChild(divChild)
divChild = addForms('serverColor', 'Server message color: ')
divWrapper.appendChild(divChild)
divChild = addForms('PMColor', 'Private message color: ')
divWrapper.appendChild(divChild)
divChild = addForms('friendColor', 'Friend color: ')
divWrapper.appendChild(divChild)
divChild = addForms('yourNameColor', 'Your name color: ')
divWrapper.appendChild(divChild)
divChild = addForms('devColor', 'Dev tag color: ')
divWrapper.appendChild(divChild)
divChild = addForms('financierColor', 'Financier tag color: ')
divWrapper.appendChild(divChild)
divChild = addForms('investorColor', 'Investor tag color: ')
divWrapper.appendChild(divChild)
divChild = addForms('moderatorColor', 'Moderator tag color: ')
divWrapper.appendChild(divChild)
//back button
let backDiv = document.createElement("div")
backDiv.onclick = () => {backButton('dialogue-color-settings', 'dialogue-extra-chat-settings')}
backDiv.className = "dialogue-button"
backDiv.appendChild(document.createTextNode("Back"))
backDiv.style = `cursor: pointer; position: absolute; top: 80%; left: 240px; background: ${mainDarkColor}; border: 1px solid ${mainOrangeColor}; color: ${mainWhiteColor}`
let resetButton = document.createElement("div")
resetButton.textContent = 'RESET COLORS'
resetButton.style = 'cursor: pointer; position: absolute; top: 90%; left: 80%; width: 75px; color: red; background: black; border: 1px solid white; border-radius: 5px;'
resetButton.onclick = () => {
loadSettingsFromStorage('resetcolors')
changeStyle('reset')
}
div.appendChild(divWrapper)
div.appendChild(resetButton)
div.appendChild(backDiv)
}
//close button
let closeDiv = document.createElement("div")
closeDiv.onclick = () => {div.style.display = "none"}
closeDiv.className = "dialogue-button"
closeDiv.appendChild(document.createTextNode("Close"))
closeDiv.style = `cursor: pointer; position: absolute; top: 80%; left: 169px; background: ${mainDarkColor}; border: 1px solid ${mainOrangeColor}; color: ${mainWhiteColor}`
div.appendChild(closeDiv)
document.getElementById(parentID).appendChild(div)
styleButtons()
}
// create button above chat
function createChatSettingsButton(){
let button = document.createElement('span')
button.onclick = (event) => openChatSettings(event,'dialogue-extra-chat-settings');
button.id = 'extra-chat-settings'
button.className = 'custom-chat-button'
button.appendChild(document.createTextNode("Settings"))
button.style = "width: 120px; font-size: 12pt"
$(button).insertBefore(chatView)
}
function createEmojiButton(){
let button = document.createElement('input')
button.id = 'emoji-send-button'
button.type = 'button'
button.className = 'chat-area-send-button'
button.style.marginLeft = '5px'
button.onclick = (event) => openChatSettings(event,'dialogue-emoji')
button.value = 'Emoji'
chatSettings.emojiButton ? button.style.display = '' : button.style.display = 'none'
$(button).insertAfter(document.querySelectorAll('.chat-area-send-button')[0])
}
// add buttons to main menu
function addButtonToSettings(id, text, key, onclick){
let div = document.createElement('div')
let button =document.createElement('button')
button.id = id
button.onclick = onclick
button.style = `background: ${mainDarkColor}; border: 1px solid ${mainLightColor}; font-size: 18px; width: 150px; height: 26px; border-radius: 5px; margin-left: 5px; color: red; text-align: left;`
button.textContent = text
if (key === 'alternateBackgrounds' || key === 'pauseAutoscroll'){
button.style.height = '52px'
}
div.appendChild(button)
return div
}
// create set words forms
function addForms(key, text){
let div = document.createElement('div')
let span = document.createElement('span')
span.textContent = text
let form = document.createElement('form')
form.id = key + '-form'
form.style = 'display: flex; flex-direction: row; align-items: center;'
let input = document.createElement('input')
input.id = key + '-input'
input.style = 'width: 300px; height: 35px; font-size: 20px;'
let button = document.createElement('button')
button.textContent = 'Save'
button.style.height = '37px'
if (key === 'exact-words'){
span.textContent += '(commas between words)'
input.value = chatSettings.exactWords
button.onclick = (event) => addWords(key + '-input', 'exact')
}else if (key === 'match-words'){
span.textContent += '(commas between words)'
input.value = chatSettings.matchWords
button.onclick = (event) => addWords(key + '-input', 'match')
}else{
input.value = chatSettings.colors[key]
button.onclick = (event) => {event.preventDefault(); changeSettings(key + '-input', key, input.value); changeStyle(key)}
div.style = 'height: 50px; padding: 3px;'
form.style.justifyContent = 'space-between'
span.style = 'margin-right: 3px; width: 160px; font-size: 12pt; font-weight: bold'
input.style = 'font-size: 16px; border: 1px solid white; height: 25px; width: 160px;'
button.style.height = '27px'
function addSpectrum(){
if($.fn.spectrum !== undefined){
$('#' + key + '-input').spectrum({
type: "text",
showButtons: false,
allowEmpty: false,
showInitial: true
})
}else{
setTimeout(addSpectrum, 1000)
}
}
addSpectrum()
}
form.appendChild(span)
form.appendChild(input)
form.appendChild(button)
div.appendChild(form)
return div
}
// create volume change element
function createAdjustableElements(key){
let div = document.createElement('div')
div.style = `font-family: sans-serif; font-size: 18px; width: 205px; height: 22px; display: flex; border: 1px solid ${mainLightColor}; flex-direction: row; justify-content: space-between; color: ${mainWhiteColor}; margin-left: 5px;`
let divChild = document.createElement('div')
divChild.style = `display: flex; flex-direction: row; justify-content: center; align-items: center; margin-left: 5px;`
let span, button
span = document.createElement('span')
span.style = `width: 150px; border-radius: 5px; padding-left: 7px; background: ${mainDarkColor}`
switch (key){
case 'volume':
span.id = 'chat-settings-volume'
span.textContent = 'Volume: ' + chatSettings.volume
div.appendChild(span)
button = createPlusMinusButton('volume', 'images/plus_tiny.png', '+')
divChild.appendChild(button)
button = createPlusMinusButton('volume', 'images/minus_tiny.png', '-')
divChild.appendChild(button)
break
case 'fontSize':
span.id = 'chat-settings-font'
span.textContent = 'Font Size: ' + chatSettings.fontSize + 'pt'
div.appendChild(span)
button = createPlusMinusButton('fontSize', 'images/plus_tiny.png', '+')
divChild.appendChild(button)
button = createPlusMinusButton('fontSize', 'images/minus_tiny.png', '-')
divChild.appendChild(button)
break
}
div.appendChild(divChild)
return div
}
function createPlusMinusButton(key, source, value){
let button = document.createElement('button')
button.style = `background: ${mainOrangeColor}; border: none; height: 22px; width: 22px; margin: 2px; display: flex; justify-content: center; align-items: center;`
switch (key){
case 'volume':
button.onclick = () => {changeSettings('chat-settings-volume', 'volume', value)}
break
case 'fontSize':
button.onclick = () => {changeSettings('chat-settings-font', 'fontSize', value)}
break
}
let img = document.createElement('img')
img.src = source
img.style.height = '12px'
img.style.width = '12px'
button.appendChild(img)
return button
}
//createListDiv(name, key)
function createListDiv(name, key){
let list
let div = document.createElement('div')
if (key === 'friend'){
list = document.getElementById('friend-list')
div.id = 'friend-' + name
}else{
list = document.getElementById('ignore-list')
div.id = 'ignored-' + name
}
div.style = `display: flex; flex-direction: row; align-items: center; height: 18px; background: ${mainDarkColor}; border-radius: 20px; margin-right: 5px; padding:3px; width: auto`
let span = document.createElement('span')
span.style = 'text-align: center; font-size: 16px; height: 18px'
span.textContent = name
div.appendChild(span)
let button = document.createElement('button')
let img = document.createElement('img')
img.src = '/images/x.png'
img.style.height = '16px'
img.style.width = '16px'
button.appendChild(img)
button.style = 'height: 20px; width: 20px; background: none; border: none; display: flex; justify-content: center; aling-items: center;'
if (key === 'friend'){
button.onclick = (event) =>{removeFromList(name, 'friend')}
}else{
button.onclick = (event) =>{removeFromList(name, 'ignore')}
}
div.appendChild(button)
list.appendChild(div)
}
// create inputs for friend list
function createInput(id){
let input = document.createElement('input')
input.id = id
input.style.height = '35px'
input.style.width = '100px'
input.style.fontSize = '20px'
return input
}
function createRightClickMenu(){
let div = document.createElement('div')
let height
div.id = 'chat-rightclick-menu'
if (playerIsMod || window.var_username === 'shtos' || window.var_username === 'pickle rick'){
height = '210px'
}else{
height = '150px'
}
div.style = `height: ${height}; width: 150px; position: absolute; display: none; flex-direction: column; align-items: center; background: #e1e1e1; border: 1px solid black; border-radius: 4px; font-family: sans-serif; font-size: 16px; z-index: 1000;`
div.onmouseleave = () => {document.getElementById('chat-rightclick-menu').style.display = 'none'}
document.getElementById('things-for-dh3').appendChild(div)
}
function createMenuButtons(){
let rightClickButtons
if (playerIsMod || window.var_username === 'shtos' || window.var_username === 'pickle rick' ){
rightClickButtons = ['PM', 'profile', 'compare', 'add friend', 'ignore', 'mute', 'ban', 'who is']
}else{
rightClickButtons = ['PM', 'profile', 'compare', 'add friend', 'ignore']
}
rightClickButtons.forEach(id=>{
let button = document.createElement('div')
button.id = 'chat-rightclick-menu-' + id
button.style = 'height: 30px; width: 147px; font-family: sans-serif; font-size: 20px; color: black; border-radius: 4px; cursor: pointer; margin-left: 1px; padding-left: 2px;'
button.textContent = id.charAt(0).toUpperCase() + id.slice(1)
button.onclick = () => {changeMenu(id)}
button.onmouseenter = () => {button.style.background = '#37dde6'}
button.onmouseleave = () => {button.style.background = '#e1e1e1'}
document.getElementById('chat-rightclick-menu').appendChild(button)
})
}
function createMuteMenu(){
let div = document.createElement('div')
div.id = 'chat-rightclick-menu-mute-settings'
div.style = 'height: 180px; width: 300px; position: absolute; display: none; flex-direction: column; align-items: center; justify-content: center; background: #e1e1e1; border: 3px solid #F56387; border-radius: 2px; font-family: sans-serif; font-size: 16px; z-index: 100;'
let inputDiv = document.createElement('div')
inputDiv.id = 'chat-rightclick-menu-mute-sub'
inputDiv.style = `display: flex; flex-direction: column; flex-wrap: wrap; justify-content: center;`
let input = document.createElement('input')
input.id = 'chat-rightclick-menu-mute-time'
input.placeholder = 'Hours'
input.style = 'width: 250px; height: 30px; font-size: 25px; margin-top: 3px;'
inputDiv.appendChild(input)
input = document.createElement('input')
input.id = 'chat-rightclick-menu-mute-type'
input.placeholder = 'Normal or IP mute'
input.style = 'width: 250px; height: 30px; font-size: 25px; margin-top: 3px;'
inputDiv.appendChild(input)
input = document.createElement('input')
input.id = 'chat-rightclick-menu-mute-reason'
input.placeholder = 'Reason'
input.style = 'width: 250px; height: 30px; font-size: 25px; margin-top: 3px;'
inputDiv.appendChild(input)
let button = document.createElement('button')
button.textContent = 'Mute'
button.style = 'border: 1px solid $F56387; margin-top: 2px'
button.onclick = () => {
mutePlayer(document.querySelectorAll('#chat-rightclick-menu-mute-sub > input'))
inputClear()
}
inputDiv.appendChild(button)
button = document.createElement('button')
button.style = 'border: 1px solid $F56387; margin-top: 2px'
button.textContent = 'Cancel'
button.onclick = () => {inputClear()}
inputDiv.appendChild(button)
div.appendChild(inputDiv)
document.getElementById('things-for-dh3').appendChild(div)
}
})();