Browse Source

refactor[#1698]: More work on moving chat out of codebase to mod

1698-move-chat-to-mod
Shaun 3 years ago
parent
commit
a25cb8c71e
9 changed files with 13 additions and 1167 deletions
  1. +0
    -208
      src/client/ui/templates/messages/channelPicker.js
  2. +0
    -382
      src/client/ui/templates/messages/messages.js
  3. +0
    -123
      src/client/ui/templates/messages/mobile.js
  4. +0
    -420
      src/client/ui/templates/messages/styles.less
  5. +0
    -20
      src/client/ui/templates/messages/template.html
  6. +0
    -1
      src/client/ui/templates/messages/tplTab.html
  7. +11
    -11
      src/server/components/social/chat.js
  8. +1
    -1
      src/server/config/serverConfig.js
  9. +1
    -1
      src/server/misc/mods.js

+ 0
- 208
src/client/ui/templates/messages/channelPicker.js View File

@@ -1,208 +0,0 @@
define([
'html!ui/templates/messages/tplTab'
], function (
tplTab
) {
const extensionObj = {
processChat: function (msgConfig) {
const { message, event: keyboardEvent } = msgConfig;
const { key } = keyboardEvent;
const { el, currentChannel } = this;

const optionContainer = this.find('.channelOptions');

if (message.length) {
if (el.hasClass('picking'))
msgConfig.cancel = true;
return;
}
if (key === 'Enter') {
const selectedSubPick = optionContainer.find('.option.selected');
if (selectedSubPick.length) {
this.onPickSubChannel(selectedSubPick.html(), currentChannel);
return;
}
}

//If we're busy picking a sub channel, we can use keyboard nav
const isPicking = el.hasClass('picking');
const currentSelection = optionContainer.find('.option.selected');
if (isPicking && currentSelection.length) {
const delta = {
ArrowUp: -1,
ArrowDown: 1
}[key];

if (delta) {
const options = optionContainer.find('.option');
const currentIndex = currentSelection.eq(0).index();
let nextIndex = (currentIndex + delta) % options.length;
currentSelection.removeClass('selected');
options.eq(nextIndex).addClass('selected');
}
}

const pick = {
'%': 'party',
'!': 'global',
$: 'custom',
'@': 'direct'
}[key];

if (!pick) {
if (isPicking)
msgConfig.cancel = true;

return;
}

if (currentChannel === pick) {
if (pick === 'direct')
this.lastPrivateChannel = null;
else if (pick === 'custom')
this.lastCustomChannel = null;
}

this.onPickChannel(pick, true);
msgConfig.cancel = true;
},

onPickChannel: function (channel, autoPickSub) {
this.currentChannel = channel;
this.currentSubChannel = null;

const showSubChannels = (
['direct', 'custom'].includes(channel) &&
(
!autoPickSub ||
(
channel === 'direct' &&
!this.lastPrivateChannel
) ||
(
channel === 'custom' &&
!this.lastCustomChannel
)
)
);

if (!showSubChannels) {
this.find('.channelOptions').removeClass('active');

let showValue = {
direct: this.lastPrivateChannel,
custom: this.lastCustomChannel
}[channel];

if (channel === 'direct' || channel === 'custom')
this.currentSubChannel = showValue;

showValue = showValue || channel;

this.find('.channelPicker').html(showValue);

this.find('input').focus();

this.el.removeClass('picking');
} else
this.onShowChannelOptions(channel);
},

onPickSubChannel: function (subChannel, channel) {
this.currentSubChannel = subChannel;
this.find('.channelOptions').removeClass('active');
this.find('.channelPicker').html(subChannel);

const elInput = this.find('input');

elInput.focus();

if (channel === 'custom') {
if (subChannel === 'join new') {
elInput.val('/join channelName');
elInput[0].setSelectionRange(6, 17);
} else if (subChannel === 'leave') {
elInput.val('/leave channelName');
elInput[0].setSelectionRange(7, 18);
}
}

this.el.removeClass('picking');
},

onShowChannelOptions: function (currentPick) {
const optionContainer = this.find('.channelOptions')
.addClass('active')
.empty();

const options = [];
let handlerOnClick = this.onPickChannel;

this.el.addClass('picking');

if (!currentPick) {
options.push('global', 'custom');

if (this.privateChannels.length)
options.push('direct');

//Hack...surely we can find a more sane way to do this
if ($('.uiParty .member').length)
options.push('party');
} else {
handlerOnClick = this.onPickSubChannel;
if (currentPick === 'direct')
options.push(...this.privateChannels);
else if (currentPick === 'custom')
options.push(...this.customChannels, 'join new', 'leave');
}

if (!options.length) {
this.onPickChannel('global');
return;
}
let addSelectStyleTo = null;
if (currentPick)
addSelectStyleTo = this.currentSubChannel || options[0];
options.forEach(o => {
const shortcut = {
global: ' (!)',
direct: ' (@)',
party: ' (%)',
custom: ' ($)'
}[o] || '';

const html = `<div class='option' shortcut='${shortcut}'>${o}</div>`;

const el = $(html)
.appendTo(optionContainer)
.on('click', handlerOnClick.bind(this, o, currentPick))
.on('hover', this.stopKeyboardNavForOptions.bind(this));

if (o === addSelectStyleTo)
el.addClass('selected');
});
},

stopKeyboardNavForOptions: function () {
this.find('.channelOptions .option.selected').removeClass('selected');
}
};

return {
init: function () {
$.extend(this, extensionObj);

//This whole hoverFilter business is a filthy hack
this.find('.channelPicker, .channelOptions, .filter:not(.channel)')
.on('mouseover', this.onFilterHover.bind(this, true))
.on('mouseleave', this.onFilterHover.bind(this, false));

this.find('.channelPicker').on('click', this.onShowChannelOptions.bind(this, null));
}
};
});

+ 0
- 382
src/client/ui/templates/messages/messages.js View File

@@ -1,382 +0,0 @@
define([
'js/system/events',
'html!ui/templates/messages/template',
'html!ui/templates/messages/tplTab',
'css!ui/templates/messages/styles',
'ui/templates/messages/mobile',
'ui/templates/messages/channelPicker',
'js/input',
'js/system/client',
'js/config'
], function (
events,
template,
tplTab,
styles,
messagesMobile,
channelPicker,
input,
client,
config
) {
return {
tpl: template,

maxChatLength: 255,

hoverItem: null,

hoverFilter: false,

currentChannel: 'global',
currentSubChannel: null,

privateChannels: [],
lastPrivateChannel: null,
customChannels: [],
lastCustomChannel: null,

postRender: function () {
[
'onGetMessages',
'onDoWhisper',
'onJoinChannel',
'onLeaveChannel',
'onClickFilter',
'onGetCustomChatChannels',
'onKeyDown',
'onKeyUp'
].forEach(e => this.onEvent(e, this[e].bind(this)));

this.find('.filter:not(.channel)').on('click', this.onClickFilter.bind(this));

channelPicker.init.call(this);

if (isMobile)
messagesMobile.init.call(this);
else {
this.find('input')
.on('keydown', this.sendChat.bind(this))
.on('input', this.enforceMaxMsgLength.bind(this))
.on('blur', this.toggle.bind(this, false, true));
}
},

update: function () {
if (isMobile)
return;
if (this.el.hasClass('typing'))
return;

const time = new Date();
const hours = time.getUTCHours().toString().padStart(2, 0);
const minutes = time.getUTCMinutes().toString().padStart(2, 0);

let elTime = this.find('.time');
const timeString = `[ ${hours}:${minutes} ]`;

if (elTime.html() !== timeString)
elTime.html(timeString);
},

enforceMaxMsgLength: function () {
let textbox = this.find('input');
let val = textbox.val();

if (val.length <= this.maxChatLength)
return;

val = val.substr(0, this.maxChatLength);
textbox.val(val);
},

onGetCustomChatChannels: function (channels) {
channels.forEach(c => this.onJoinChannel(c));
},

onJoinChannel: function (channel) {
const container = this.find('.filters');

const channelName = channel.trim();

this.customChannels.spliceWhere(c => c === channel);
this.find(`[filter="${channelName}"]`).remove();

this.customChannels.push(channel);

$(tplTab)
.appendTo(container)
.addClass('channel')
.attr('filter', channelName)
.html(channelName)
.on('mouseover', this.onFilterHover.bind(this, true))
.on('mouseleave', this.onFilterHover.bind(this, false))
.on('click', this.onClickFilter.bind(this));
},

onLeaveChannel: function (channel) {
this.customChannels.spliceWhere(c => c === channel);

this.find(`.filters div[filter="${channel}"]`).remove();
},

onFilterHover: function (hover) {
this.hoverFilter = hover;
},

onClickFilter: function (e) {
let el = $(e.target);
el.toggleClass('active');

let filter = el.attr('filter');
let method = (el.hasClass('active') ? 'show' : 'hide');

if (method === 'show')
this.find('.list').addClass(filter);
else
this.find('.list').removeClass(filter);

if (el.hasClass('channel'))
this.find('.list .' + filter)[method]();
},

onKeyDown: function (key) {
if (key === 'enter')
this.toggle(true);
else if (key === 'shift')
this.showItemTooltip();
else if (key === 'esc' && this.el.hasClass('typing'))
this.toggle(false);
},

onKeyUp: function (key) {
if (key === 'shift')
this.showItemTooltip();
},

onDoWhisper: function (charName) {
this.toggle(true);

this.currentChannel = 'direct';
this.currentSubChannel = charName;

this.find('.channelPicker').html(charName);

const elInput = this.find('input')
.val('message')
.focus();

elInput[0].setSelectionRange(0, 7);
},

//Remember private and custom channels used
trackHistory: function (msg) {
const { subType, source, target, channel } = msg;

if (subType === 'privateIn' || subType === 'privateOut') {
const list = this.privateChannels;
list.spliceWhere(l => l === source || l === target);

//Newest sources are always at the end
list.push(source || target);

if (list.length > 5)
list.splice(0, list.length - 5);

if (subType === 'privateOut' && config.rememberChatChannel)
this.lastPrivateChannel = target;
} else if (subType === 'custom' && config.rememberChatChannel)
this.lastCustomChannel = channel;
},

onGetMessages: function (e) {
let messages = e.messages;
if (!messages.length)
messages = [messages];

let container = this.find('.list');

const [ { scrollHeight, clientHeight, scrollTop } ] = container;
const isAtMaxScroll = scrollTop >= (scrollHeight - clientHeight);

messages.forEach(m => {
this.trackHistory(m);

let message = m.message;

if (m.source) {
if (window.player.social.isPlayerBlocked(m.source))
return;
}

if (m.item) {
let source = message.split(':')[0];
message = source + ': <span class="q' + (m.item.quality || 0) + '">' + message.replace(source + ': ', '') + '</span>';
}

let el = $('<div class="list-message ' + m.class + '">' + message + '</div>')
.appendTo(container);

if (m.has('type'))
el.addClass(m.type);
else
el.addClass('info');

if (m.has('channel'))
el.addClass(m.channel);

if (m.item) {
let clickHander = () => {};
let moveHandler = this.showItemTooltip.bind(this, el, m.item);
if (isMobile)
[clickHander, moveHandler] = [moveHandler, clickHander];

el.find('span')
.on('mousemove', moveHandler)
.on('mousedown', clickHander)
.on('mouseleave', this.hideItemTooltip.bind(this));
}

if (m.type) {
let isChannel = (['info', 'chat', 'loot', 'rep'].indexOf(m.type) === -1);
if (isChannel) {
if (this.find('.filter[filter="' + m.type + '"]').hasClass('active'))
el.show();
}

if (isMobile && ['loot', 'info'].indexOf(m.type) !== -1) {
events.emit('onGetAnnouncement', {
msg: m.message
});
}
}
});

if (!this.el.hasClass('typing') || isAtMaxScroll)
container.scrollTop(9999999);
},

hideItemTooltip: function () {
if (this.dragEl) {
this.hoverCell = null;
return;
}

events.emit('onHideItemTooltip', this.hoverItem);
this.hoverItem = null;
},

showItemTooltip: function (el, item, e) {
if (item)
this.hoverItem = item;
else
item = this.hoverItem;

if (!item)
return;

let ttPos = null;
if (el) {
ttPos = {
x: ~~(e.clientX + 32),
y: ~~(e.clientY)
};
}

let bottomAlign = !isMobile;

events.emit('onShowItemTooltip', item, ttPos, true, bottomAlign);
},

toggle: function (show, isFake, e) {
if (isFake && this.hoverFilter)
return;

input.resetKeys();

this.el.removeClass('typing');

let textbox = this.find('input');

if (show) {
this.el.addClass('typing');

if (!config.rememberChatChannel) {
this.currentChannel = 'global';
this.currentSubChannel = null;
}

this.find('.channelPicker').html(this.currentSubChannel || this.currentChannel);
textbox.focus();
this.find('.list').scrollTop(9999999);
} else {
this.find('.channelOptions').removeClass('active');
textbox.val('');
this.el.removeClass('picking');

if (['direct', 'custom'].includes(this.currentChannel) && (!this.currentSubChannel || ['join new', 'leave'].includes(this.currentSubChannel))) {
this.currentSubChannel = null;
this.currentChannel = 'global';
}
}

if (e)
e.stopPropagation();
},

sendChat: function (e) {
let textbox = this.find('input');
let msgConfig = {
success: true,
message: textbox.val(),
event: e,
cancel: false
};

this.processChat(msgConfig);
if (msgConfig.cancel || this.el.hasClass('picking'))
return false;

const { which: charCode } = e;

if ([9, 27].includes(charCode) || charCode !== 13) {
if (charCode === 9) {
e.preventDefault();
textbox.val(`${textbox.val()} `);
} else if (charCode === 27)
this.toggle(false);

return;
}

events.emit('onBeforeChat', msgConfig);

let val = msgConfig.message
.split('<').join('&lt;')
.split('>').join('&gt;');

if (!msgConfig.success) {
this.toggle(false);
return;
}

if (val.trim() === '') {
this.toggle(false);
return;
}

client.request({
cpn: 'social',
method: 'chat',
data: {
message: val,
type: this.currentChannel,
subType: this.currentSubChannel
}
});

this.toggle();
}
};
});

+ 0
- 123
src/client/ui/templates/messages/mobile.js View File

@@ -1,123 +0,0 @@
define([
'html!ui/templates/messages/tplTab'
], function (
tplTab
) {
const extensionObj = {
renderKeyboard: function () {
this.find('.keyboard').remove();

let container = $('<div class="keyboard"></div>')
.appendTo(this.el);

let keyboard = {
0: 'qwertyuiop|asdfghjkl|zxcvbnm',
1: 'QWERTYUIOP|ASDFGHJKL|ZXCVBNM',
2: '1234567890|@#&*-+=()|_$"\';/'
}[this.kbUpper].split('');

//Hacky: Insert control characters in correct positions
//Backspace goes after 'm'
if (this.kbUpper === 0) {
keyboard.splice(keyboard.indexOf('z'), 0, 'caps');
keyboard.splice(keyboard.indexOf('m') + 1, 0, '<<');
} else if (this.kbUpper === 1) {
keyboard.splice(keyboard.indexOf('Z'), 0, 'caps');
keyboard.splice(keyboard.indexOf('M') + 1, 0, '<<');
} else if (this.kbUpper === 2)
keyboard.splice(keyboard.indexOf('/') + 1, 0, '<<');

keyboard.push(...['|', '123', ',', 'space', '.', 'send']);

let row = 0;
keyboard.forEach(k => {
if (k === '|') {
row++;

const postGapCount = row === 4 ? 0 : row - 1;
for (let i = 0; i < postGapCount; i++)
$('<div class="gap" />').appendTo(container);
$('<div class="newline" />').appendTo(container);
const preGapCount = row === 3 ? 0 : row;
for (let i = 0; i < preGapCount; i++)
$('<div class="gap" />').appendTo(container);

return;
}

let className = (k.length === 1) ? 'key' : 'key special';
if (k === ' ') {
k = '.';
className = 'key hidden';
}

className += ' ' + k;

let elKey = $(`<div class="${className}">${k}</div>`)
.appendTo(container);

if (!className.includes('hidden'))
elKey.on('click', this.clickKey.bind(this, k));
});
},

clickKey: function (key) {
window.navigator.vibrate(20);

let elInput = this.find('input');

const handler = {
caps: () => {
this.kbUpper = (this.kbUpper + 1) % 2;
this.renderKeyboard();
},

123: () => {
this.kbUpper = (this.kbUpper === 2) ? 0 : 2;
this.renderKeyboard();
},

space: () => this.clickKey(' '),

'<<': () => {
elInput.val(elInput.val().slice(0, -1));
this.find('.input').html(elInput.val());
},

send: () => {
this.sendChat({ which: 13 });
this.find('.input').html('');
this.find('input').val('');
}
}[key];
if (handler) {
handler();
return;
}

elInput.val(elInput.val() + key);
this.enforceMaxMsgLength();

this.find('.input').html(elInput.val());
}
};

return {
init: function () {
$.extend(this, extensionObj);

this.kbUpper = 0;

this.el.on('click', this.toggle.bind(this, true));
this.renderKeyboard();

$(tplTab)
.appendTo(this.find('.filters'))
.addClass('btnClose')
.html('x')
.on('click', this.toggle.bind(this, false, true));
}
};
});

+ 0
- 420
src/client/ui/templates/messages/styles.less View File

@@ -1,420 +0,0 @@
@import "../../../css/colors.less";
@pad: 8px;
@btnSize: 64px;

.uiMessages {
position: absolute;
left: 10px;
bottom: 10px;
width: 480px;
pointer-events: none;
display: flex;
flex-direction: column;

.filters {
display: none;
width: 100%;
flex-wrap: wrap;

.filter {
height: 100%;
background-color: @blackC;
float: left;
color: @blackA;
margin-right: 10px;
margin-bottom: 10px;
padding: 5px 10px;
cursor: pointer;

&:hover {
background-color: @blackB;
color: @grayD;
}

&.active {
background-color: @blackB;
color: @blueB;

&:hover {
background-color: @blackA;
color: @grayB;
}

}

}

}

.list {
overflow-y: hidden;
width: 100%;
max-height: 320px;

.list-message {
display: none;
width: 100%;
padding: 5px 10px;
color: white;
filter: drop-shadow(0px -2px 0px @blackD)
drop-shadow(0px 2px 0px @blackD)
drop-shadow(2px 0px 0px @blackD)
drop-shadow(-2px 0px 0px @blackD);
-moz-filter: drop-shadow(0px -2px 0px @blackD)
drop-shadow(0px 2px 0px @blackD)
drop-shadow(2px 0px 0px @blackD)
drop-shadow(-2px 0px 0px @blackD);
word-wrap: break-word;
line-height: 18px;

&.q {
color: @grayB;
}

&.q0 {
color: @white;
}

&.q1 {
color: @greenB;
}

a,
&.q2 {
color: @blueB;
}

&.q3 {
color: @purpleA;
}

&.q4 {
color: @orangeA;
}

&.color-green {
color: @green;
}

&.color-red {
color: @red;
}

&.color-cyan {
color: @blueA;
}

&.color-tealC {
color: @tealC;
}

}

&.rep .rep {
display: block;
}

&.chat .chat {
display: block;
}

&.info .info {
display: block;
}

&.loot .loot {
display: block;
}

}

.bottom {
display: none;

.channelPicker {
min-width: 100px;
color: 1;
display: flex;
justify-content: center;
align-items: center;
color: @white;
background-color: @blueC;
cursor: pointer;
padding: 0px 10px;

&:after {
content: '▾';
margin-left: 10px;
}

&:hover {
background-color: @blueD;
}

}

.el {
flex: 1;
width: 100%;
color: @white;

&.textbox.message {
display: none;
background-color: @gray;
text-align: left;
padding: 5px 10px;
}

}

&.time {
display: flex;
align-items: center;
padding-left: 10px;
background-color: transparent;
height: 35px;
color: @white;
text-align: left;
filter: drop-shadow(0px -2px 0px @blackD)
drop-shadow(0px 2px 0px @blackD)
drop-shadow(2px 0px 0px @blackD)
drop-shadow(-2px 0px 0px @blackD);
-moz-filter: drop-shadow(0px -2px 0px @blackD)
drop-shadow(0px 2px 0px @blackD)
drop-shadow(2px 0px 0px @blackD)
drop-shadow(-2px 0px 0px @blackD);
}

&.channelOptions {
display: none;
flex-direction: column;
position: absolute;
left: 0px;
bottom: 0px;
min-width: 100px;

.option {
height: 35px;
display: flex;
justify-content: center;
align-items: center;
color: @grayB;
background-color: @blackA;
cursor: pointer;
padding: 0px 10px;

&:after {
content: attr(shortcut);
margin-left: 10px;
color: @grayC;
}

&:hover,
&.selected {
background-color: @grayD;
color: @white;
}

}

}

}

&.typing {
box-shadow: 0 -2px 0 @black, 0 2px 0 @black, 2px 0 0 @black, -2px 0 0 @black;
pointer-events: all;

.filters {
pointer-events: all;
display: flex;
}

.list {
overflow-y: auto;
background-color: @darkGray;

.list-message {
filter: none;
}

}

.bottom {
display: flex;

.el.textbox {
&.message:not(.input) {
display: block;
}

}

}

.time {
display: none;
}

.channelOptions {
display: none;

&.active {
display: flex;
}

}

}

&.active {
.list-message {
opacity: 1 !important;
}

}

&.picking {
&:before {
position: absolute;
content: '';
left: 0px;
top: 0px;
width: 100%;
height: 100%;
background-color: @blackD;
opacity: 0.7;
}

}

}

.mobile .uiMessages {
padding: 0px;
pointer-events: all;

.btnClose.active {
float: right;
margin-right: 0px;
padding: 5px 20px;
color: @redA;
}

input {
display: none;
}

.filters {
margin-bottom: 0px;
flex-shrink: 0;
background-color: @darkGray;
}

.list {
height: 100%;
max-height: 100%;
}

&.typing {
left: 0px;
top: 0px;
width: 100%;
height: 100%;
background-color: fade(@darkGray, 90%);
display: flex;
flex-direction: column;
z-index: 999999998;

.channelPicker {
display: none;
}

.channelOptions {
z-index: 999999999;
}

.bottom {
.input {
display: block;
height: 26px;
flex-shrink: 0;
}

}

.el.textbox.message:not(.input),.time {
display: none;
}

.keyboard {
display: flex;
flex-direction: row;
flex-wrap: wrap;
background-color: @blackC;
justify-content: center;
align-items: center;
height: 140px;
flex-shrink: 0;

.key {
flex: 1;
background-color: @blackA;
color: @white;
padding: 8px 10px;
text-align: center;

&.special {
color: @orangeA;
}

&.hidden {
color: @blackC;
}

&.space {
flex: 5;
}

}

.newline {
width: 100%;
}

.gap {
width: 5%;
flex-shrink: 0;
}

}

}

&:not(.typing) {
top: 10px;
right: 84px;
left: auto;
bottom: auto;
width: @btnSize;
height: @btnSize;
background-color: fade(@darkGray, 90%);

&:after {
content: '';
position: absolute;
left: 0px;
top: 0px;
background: url('../../../images/uiIcons.png');
background-position: -0px -128px;
width: @btnSize;
height: @btnSize;
}

> * {
display: none;
}

}

}

+ 0
- 20
src/client/ui/templates/messages/template.html View File

@@ -1,20 +0,0 @@
<div class="uiMessages active">
<div class="filters">
<div class="btn filter active" filter="info">info</div>
<div class="btn filter active" filter="rep">reputation</div>
<div class="btn filter active" filter="chat">players</div>
<div class="btn filter active" filter="loot">loot</div>
</div>
<div class="list rep chat info loot"></div>
<div class="bottom">
<div class="channelPicker"></div>
<input type="text" class="el textbox message">
<div class="input el textbox message"></div>
</div>
<div class="bottom time"></div>
<div class="bottom channelOptions">
<div class="option">global</div>
<div class="option">party</div>
<div class="option">direct</div>
</div>
</div>

+ 0
- 1
src/client/ui/templates/messages/tplTab.html View File

@@ -1 +0,0 @@
<div class="filter active" filter="filterName"></div>

+ 11
- 11
src/server/components/social/chat.js View File

@@ -11,19 +11,19 @@ const sendRegularMessage = ({ obj }, messageInfo) => {

const msgClass = item ? `q${item.quality}` : 'color-grayB';

const msgData = {
type: 'chat',
source,
prefix,
prefixClass,
msg,
msgClass,
item
};

cons.emit('event', {
event: 'onGetMessages',
data: {
messages: [{
type: 'chat',
source,
prefix,
prefixClass,
msg,
msgClass,
item
}]
}
data: { messages: [msgData] }
});
};



+ 1
- 1
src/server/config/serverConfig.js View File

@@ -8,7 +8,7 @@ module.exports = {
// sqlite
// rethink
//eslint-disable-next-line no-process-env
db: process.env.IWD_DB || 'rethink',
db: process.env.IWD_DB || 'sqlite',
//eslint-disable-next-line no-process-env
dbHost: process.env.IWD_DB_HOST || 'localhost',
//eslint-disable-next-line no-process-env


+ 1
- 1
src/server/misc/mods.js View File

@@ -49,7 +49,7 @@ module.exports = {
if (mod.disabled)
return;

const isMapThread = !!process.send;
const isMapThread = global.instancer;
mod.isMapThread = isMapThread;

mod.events = events;


Loading…
Cancel
Save