[MIRROR] TG-Chat visual limits and fixes (#7580)

Co-authored-by: Kashargul <144968721+Kashargul@users.noreply.github.com>
Co-authored-by: Selis <selis@xynolabs.com>
This commit is contained in:
CHOMPStation2
2024-01-18 16:20:48 -07:00
committed by GitHub
parent afb4a56f7d
commit 27623e4bd4
23 changed files with 460 additions and 193 deletions
+6
View File
@@ -0,0 +1,6 @@
/client/verb/export_chat()
set category = "OOC"
set name = "Export Chatlog"
set desc = "Allows to trigger the chat export"
to_chat(usr, "<span data-command=\"$do_export\"></span>")
+4 -4
View File
@@ -1037,7 +1037,7 @@
//Print notifications/sound if necessary
if(!silent && count)
owner.visible_message("<font color='green'><b>[owner] [release_verb] everything from their [lowertext(name)]!</b></font>", range = privacy_range)
owner.visible_message("<span class='vnotice'><font color='green'><b>[owner] [release_verb] everything from their [lowertext(name)]!</b></font></span>", range = privacy_range)
var/soundfile
if(!fancy_vore)
soundfile = classic_release_sounds[release_sound]
@@ -1119,7 +1119,7 @@
if(istype(M, /mob/observer)) //CHOMPEdit
silent = TRUE
if(!silent)
owner.visible_message("<font color='green'><b>[owner] [release_verb] [M] from their [lowertext(name)]!</b></font>",range = privacy_range)
owner.visible_message("<span class='vnotice'><font color='green'><b>[owner] [release_verb] [M] from their [lowertext(name)]!</b></font></span>",range = privacy_range)
var/soundfile
if(!fancy_vore)
soundfile = classic_release_sounds[release_sound]
@@ -1191,7 +1191,7 @@
formatted_message = replacetext(formatted_message, "%countprey", living_count)
formatted_message = replacetext(formatted_message, "%count", contents.len)
return("<span class='vwarning'>[formatted_message]</span>")
return("<i><font color='red'>[formatted_message]</font></i>")
/obj/belly/proc/get_examine_msg_absorbed()
if(!(contents.len) || !(examine_messages_absorbed.len) || !display_absorbed_examine)
@@ -1215,7 +1215,7 @@
formatted_message = replacetext(formatted_message, "%prey", english_list(absorbed_victims))
formatted_message = replacetext(formatted_message, "%countprey", absorbed_count)
return("<span class='vwarning'>[formatted_message]</span>")
return("<i><font color='red'>[formatted_message]</font></i>")
// The next function gets the messages set on the belly, in human-readable format.
// This is useful in customization boxes and such. The delimiter right now is \n\n so
+8 -6
View File
@@ -83,12 +83,14 @@ export const Panel = (props, context) => {
<ChatPanel lineHeight={settings.lineHeight} />
</Pane.Content>
<Notifications>
{settings.showReconnectWarning && game.connectionLostAt && (
<Notifications.Item rightSlot={<ReconnectButton />}>
You are either AFK, experiencing lag or the connection has
closed.
</Notifications.Item>
)}
{settings.showReconnectWarning &&
game.connectionLostAt &&
!game.dismissedConnectionWarning && (
<Notifications.Item rightSlot={<ReconnectButton />}>
You are either AFK, experiencing lag or the connection has
closed.
</Notifications.Item>
)}
{settings.showReconnectWarning && game.roundRestartedAt && (
<Notifications.Item>
The connection has been closed because the server is
@@ -6,7 +6,7 @@
import { useDispatch, useSelector } from 'common/redux';
import { Button, Collapsible, Divider, Input, Section, Stack } from 'tgui_ch/components'; // CHOMPEdit - tgui_ch
import { removeChatPage, toggleAcceptedType, updateChatPage } from './actions';
import { moveChatPageLeft, moveChatPageRight, removeChatPage, toggleAcceptedType, updateChatPage } from './actions';
import { MESSAGE_TYPES } from './constants';
import { selectCurrentChatPage } from './selectors';
@@ -30,20 +30,56 @@ export const ChatPageSettings = (props, context) => {
}
/>
</Stack.Item>
<Stack.Item>
<Button
icon="times"
color="red"
onClick={() =>
dispatch(
removeChatPage({
pageId: page.id,
})
)
}>
Remove
</Button>
</Stack.Item>
{!page.isMain ? (
<Stack.Item>
<Button
icon="times"
color="red"
onClick={() =>
dispatch(
removeChatPage({
pageId: page.id,
})
)
}>
Remove
</Button>
</Stack.Item>
) : (
''
)}
</Stack>
<Divider />
<Stack align="center">
{!page.isMain ? (
<Stack.Item>
Reorder Chat:&emsp;
<Button
color="blue"
onClick={() =>
dispatch(
moveChatPageLeft({
pageId: page.id,
})
)
}>
&laquo;
</Button>
<Button
color="blue"
onClick={() =>
dispatch(
moveChatPageRight({
pageId: page.id,
})
)
}>
&raquo;
</Button>
</Stack.Item>
) : (
''
)}
</Stack>
<Divider />
<Section title="Messages to display" level={2}>
+2
View File
@@ -20,3 +20,5 @@ export const removeChatPage = createAction('chat/removePage');
export const changeScrollTracking = createAction('chat/changeScrollTracking');
export const saveChatToDisk = createAction('chat/saveToDisk');
export const purgeChatMessageArchive = createAction('chat/purgeMessageArchive');
export const moveChatPageLeft = createAction('chat/movePageLeft');
export const moveChatPageRight = createAction('chat/movePageRight');
+4 -4
View File
@@ -4,12 +4,12 @@
* @license MIT
*/
export const MAX_VISIBLE_MESSAGES = 2500;
export const MAX_PERSISTED_MESSAGES = 1000;
// export const MAX_VISIBLE_MESSAGES = 2500; No longer a constant
// export const MAX_PERSISTED_MESSAGES = 1000; No longer a constant
export const MESSAGE_SAVE_INTERVAL = 10000;
export const MESSAGE_PRUNE_INTERVAL = 60000;
export const COMBINE_MAX_MESSAGES = 5;
export const COMBINE_MAX_TIME_WINDOW = 5000;
// export const COMBINE_MAX_MESSAGES = 5; No longer a constant
// export const COMBINE_MAX_TIME_WINDOW = 5000; No longer a constant
export const IMAGE_RETRY_DELAY = 250;
export const IMAGE_RETRY_LIMIT = 10;
export const IMAGE_RETRY_MESSAGE_AGE = 60000;
+19 -9
View File
@@ -8,8 +8,8 @@ import DOMPurify from 'dompurify';
import { storage } from 'common/storage';
import { loadSettings, updateSettings, addHighlightSetting, removeHighlightSetting, updateHighlightSetting } from '../settings/actions';
import { selectSettings } from '../settings/selectors';
import { addChatPage, changeChatPage, changeScrollTracking, loadChat, rebuildChat, removeChatPage, saveChatToDisk, purgeChatMessageArchive, toggleAcceptedType, updateMessageCount } from './actions';
import { MAX_PERSISTED_MESSAGES, MESSAGE_SAVE_INTERVAL } from './constants';
import { addChatPage, changeChatPage, changeScrollTracking, loadChat, rebuildChat, moveChatPageLeft, moveChatPageRight, removeChatPage, saveChatToDisk, purgeChatMessageArchive, toggleAcceptedType, updateMessageCount } from './actions';
import { MESSAGE_SAVE_INTERVAL } from './constants';
import { createMessage, serializeMessage } from './model';
import { chatRenderer } from './renderer';
import { selectChat, selectCurrentChatPage } from './selectors';
@@ -19,9 +19,10 @@ const FORBID_TAGS = ['a', 'iframe', 'link', 'video'];
const saveChatToStorage = async (store) => {
const state = selectChat(store.getState());
const settings = selectSettings(store.getState());
const fromIndex = Math.max(
0,
chatRenderer.messages.length - MAX_PERSISTED_MESSAGES
chatRenderer.messages.length - settings.persistentMessageLimit
);
const messages = chatRenderer.messages
.slice(fromIndex)
@@ -61,7 +62,6 @@ const loadChatFromStorage = async (store) => {
];
chatRenderer.processBatch(batch, {
prepend: true,
noarchive: true,
});
}
if (archivedMessages) {
@@ -116,6 +116,14 @@ export const chatMiddleware = (store) => {
}, MESSAGE_SAVE_INTERVAL);
return (next) => (action) => {
const { type, payload } = action;
const settings = selectSettings(store.getState());
settings.totalStoredMessages = chatRenderer.getStoredMessages();
chatRenderer.setVisualChatLimits(
settings.visibleMessageLimit,
settings.combineMessageLimit,
settings.combineIntervalLimit,
settings.logLineCount
);
if (!initialized) {
initialized = true;
loadChatFromStorage(store);
@@ -155,7 +163,9 @@ export const chatMiddleware = (store) => {
}
}
chatRenderer.processBatch([payload_obj.content]);
chatRenderer.processBatch([payload_obj.content], {
doArchive: true,
});
return;
}
if (type === loadChat.type) {
@@ -170,7 +180,9 @@ export const chatMiddleware = (store) => {
type === changeChatPage.type ||
type === addChatPage.type ||
type === removeChatPage.type ||
type === toggleAcceptedType.type
type === toggleAcceptedType.type ||
type === moveChatPageLeft.type ||
type === moveChatPageRight.type
) {
next(action);
const page = selectCurrentChatPage(store.getState());
@@ -178,7 +190,7 @@ export const chatMiddleware = (store) => {
return;
}
if (type === rebuildChat.type) {
chatRenderer.rebuildChat();
chatRenderer.rebuildChat(settings.visibleMessages);
return next(action);
}
@@ -190,7 +202,6 @@ export const chatMiddleware = (store) => {
type === updateHighlightSetting.type
) {
next(action);
const settings = selectSettings(store.getState());
chatRenderer.setHighlight(
settings.highlightSettings,
settings.highlightSettingById
@@ -204,7 +215,6 @@ export const chatMiddleware = (store) => {
return next(action);
}
if (type === saveChatToDisk.type) {
const settings = selectSettings(store.getState());
chatRenderer.saveToDisk(settings.logLineCount);
return;
}
+2
View File
@@ -18,6 +18,7 @@ export const createPage = (obj) => {
}
return {
isMain: false,
id: createUuid(),
name: 'New Tab',
acceptedTypes: acceptedTypes,
@@ -33,6 +34,7 @@ export const createMainPage = () => {
acceptedTypes[typeDef.type] = true;
}
return createPage({
isMain: true,
name: 'Main',
acceptedTypes,
});
+48 -1
View File
@@ -4,7 +4,7 @@
* @license MIT
*/
import { addChatPage, changeChatPage, loadChat, removeChatPage, toggleAcceptedType, updateChatPage, updateMessageCount, changeScrollTracking } from './actions';
import { addChatPage, changeChatPage, loadChat, removeChatPage, moveChatPageLeft, moveChatPageRight, toggleAcceptedType, updateChatPage, updateMessageCount, changeScrollTracking } from './actions';
import { canPageAcceptType, createMainPage } from './model';
const mainPage = createMainPage();
@@ -179,5 +179,52 @@ export const chatReducer = (state = initialState, action) => {
}
return nextState;
}
if (type === moveChatPageLeft.type) {
const { pageId } = payload;
const nextState = {
...state,
pages: [...state.pages],
pageById: {
...state.pageById,
},
};
const tmpPage = nextState.pageById[pageId];
const fromIndex = nextState.pages.indexOf(tmpPage.id);
const toIndex = fromIndex - 1;
// don't ever move leftmost page
if (fromIndex > 0) {
// don't ever move anything to the leftmost page
if (toIndex > 0) {
const tmp = nextState.pages[fromIndex];
nextState.pages[fromIndex] = nextState.pages[toIndex];
nextState.pages[toIndex] = tmp;
}
}
return nextState;
}
if (type === moveChatPageRight.type) {
const { pageId } = payload;
const nextState = {
...state,
pages: [...state.pages],
pageById: {
...state.pageById,
},
};
const tmpPage = nextState.pageById[pageId];
const fromIndex = nextState.pages.indexOf(tmpPage.id);
const toIndex = fromIndex + 1;
// don't ever move leftmost page
if (fromIndex > 0) {
// don't ever move anything out of the array
if (toIndex < nextState.pages.length) {
const tmp = nextState.pages[fromIndex];
nextState.pages[fromIndex] = nextState.pages[toIndex];
nextState.pages[toIndex] = tmp;
}
}
return nextState;
}
return state;
};
+50 -21
View File
@@ -7,7 +7,7 @@
import { EventEmitter } from 'common/events';
import { classes } from 'common/react';
import { createLogger } from 'tgui_ch/logging'; // CHOMPEdit - tgui_ch
import { COMBINE_MAX_MESSAGES, COMBINE_MAX_TIME_WINDOW, IMAGE_RETRY_DELAY, IMAGE_RETRY_LIMIT, IMAGE_RETRY_MESSAGE_AGE, MAX_PERSISTED_MESSAGES, MAX_VISIBLE_MESSAGES, MESSAGE_PRUNE_INTERVAL, MESSAGE_TYPES, MESSAGE_TYPE_INTERNAL, MESSAGE_TYPE_UNKNOWN } from './constants';
import { IMAGE_RETRY_DELAY, IMAGE_RETRY_LIMIT, IMAGE_RETRY_MESSAGE_AGE, MESSAGE_PRUNE_INTERVAL, MESSAGE_TYPES, MESSAGE_TYPE_INTERNAL, MESSAGE_TYPE_UNKNOWN } from './constants';
import { render } from 'inferno';
import { canPageAcceptType, createMessage, isSameMessage, serializeMessage } from './model';
import { highlightNode, linkifyNode } from './replaceInTextNode';
@@ -115,6 +115,11 @@ class ChatRenderer {
this.visibleMessages = [];
this.page = null;
this.events = new EventEmitter();
// Adjustables
this.visibleMessageLimit = 2500;
this.combineMessageLimit = 5;
this.combineIntervalLimit = 5;
this.exportLimit = -1;
// Scroll handler
/** @type {HTMLElement} */
this.scrollNode = null;
@@ -160,7 +165,7 @@ class ChatRenderer {
this.scrollToBottom();
});
// Flush the queue
this.tryFlushQueue();
this.tryFlushQueue(true);
}
onStateLoaded() {
@@ -168,9 +173,9 @@ class ChatRenderer {
this.tryFlushQueue();
}
tryFlushQueue() {
tryFlushQueue(doArchive = false) {
if (this.isReady() && this.queue.length > 0) {
this.processBatch(this.queue);
this.processBatch(this.queue, { doArchive: doArchive });
this.queue = [];
}
}
@@ -352,22 +357,33 @@ class ChatRenderer {
}
}
setVisualChatLimits(
visibleMessageLimit,
combineMessageLimit,
combineIntervalLimit,
exportLimit
) {
this.visibleMessageLimit = visibleMessageLimit;
this.combineMessageLimit = combineMessageLimit;
this.combineIntervalLimit = combineIntervalLimit;
this.exportLimit = exportLimit;
}
getCombinableMessage(predicate) {
const now = Date.now();
const len = this.visibleMessages.length;
const from = len - 1;
const to = Math.max(0, len - COMBINE_MAX_MESSAGES);
const to = Math.max(0, len - this.combineMessageLimit);
for (let i = from; i >= to; i--) {
const message = this.visibleMessages[i];
// prettier-ignore
const matches = (
const matches =
// Is not an internal message
!message.type.startsWith(MESSAGE_TYPE_INTERNAL)
!message.type.startsWith(MESSAGE_TYPE_INTERNAL) &&
// Text payload must fully match
&& isSameMessage(message, predicate)
isSameMessage(message, predicate) &&
// Must land within the specified time window
&& now < message.createdAt + COMBINE_MAX_TIME_WINDOW
);
now < message.createdAt + this.combineIntervalLimit * 1000;
if (matches) {
return message;
}
@@ -376,7 +392,7 @@ class ChatRenderer {
}
processBatch(batch, options = {}) {
const { prepend, notifyListeners = true, noArchive = false } = options;
const { prepend, notifyListeners = true, doArchive = false } = options;
const now = Date.now();
// Queue up messages until chat is ready
if (!this.isReady()) {
@@ -421,6 +437,15 @@ class ChatRenderer {
} else {
logger.error('Error: message is missing text payload', message);
}
// Get our commands we might want to send to chat
const commands = node.querySelectorAll('[data-command]');
if (commands.length) {
const command = commands[0].getAttribute('data-command');
if (command === '$do_export') {
this.saveToDisk(this.exportLimit);
}
return; // We do not want those logged or shown!
}
// Get all nodes in this message that want to be rendered like jsx
const nodes = node.querySelectorAll('[data-component]');
for (let i = 0; i < nodes.length; i++) {
@@ -521,7 +546,7 @@ class ChatRenderer {
countByType[message.type] += 1;
// TODO: Detect duplicates
this.messages.push(message);
if (!noArchive) {
if (doArchive) {
this.archivedMessages.push(serializeMessage(message, true)); // TODO: Actually having a better message archiving maybe for exports?
}
if (canPageAcceptType(this.page, message.type)) {
@@ -559,7 +584,7 @@ class ChatRenderer {
// Visible messages
{
const messages = this.visibleMessages;
const fromIndex = Math.max(0, messages.length - MAX_VISIBLE_MESSAGES);
const fromIndex = Math.max(0, messages.length - this.visibleMessageLimit);
if (fromIndex > 0) {
this.visibleMessages = messages.slice(fromIndex);
for (let i = 0; i < fromIndex; i++) {
@@ -580,7 +605,7 @@ class ChatRenderer {
{
const fromIndex = Math.max(
0,
this.messages.length - MAX_PERSISTED_MESSAGES
this.messages.length - this.persistentMessageLimit
);
if (fromIndex > 0) {
this.messages = this.messages.slice(fromIndex);
@@ -589,15 +614,12 @@ class ChatRenderer {
}
}
rebuildChat() {
rebuildChat(rebuildLimit) {
if (!this.isReady()) {
return;
}
// Make a copy of messages
const fromIndex = Math.max(
0,
this.messages.length - MAX_PERSISTED_MESSAGES
);
const fromIndex = Math.max(0, this.messages.length - rebuildLimit);
const messages = this.messages.slice(fromIndex);
// Remove existing nodes
for (let message of messages) {
@@ -643,10 +665,13 @@ class ChatRenderer {
// for (let message of this.visibleMessages) { // TODO: Actually having a better message archiving maybe for exports?
for (let message of tmpMsgArray) {
// Filter messages according to active tab for export
if (canPageAcceptType(this.page, message.type)) {
messagesHtml += message.html + '\n';
}
// if (message.node) {
// messagesHtml += message.node.outerHTML + '\n';
// }
messagesHtml += message.html + '\n';
}
// Create a page
// prettier-ignore
@@ -675,6 +700,10 @@ class ChatRenderer {
purgeMessageArchive() {
this.archivedMessages = [];
}
getStoredMessages() {
return this.archivedMessages.length;
}
}
// Make chat renderer global so that we can continue using the same
+1
View File
@@ -9,3 +9,4 @@ import { createAction } from 'common/redux';
export const roundRestarted = createAction('roundrestart');
export const connectionLost = createAction('game/connectionLost');
export const connectionRestored = createAction('game/connectionRestored');
export const dismissWarning = createAction('game/dismissWarning');
+9 -1
View File
@@ -5,7 +5,7 @@
*/
import { connectionLost } from './actions';
import { connectionRestored } from './actions';
import { connectionRestored, dismissWarning } from './actions';
const initialState = {
// TODO: This is where round info should be.
@@ -13,6 +13,7 @@ const initialState = {
roundTime: null,
roundRestartedAt: null,
connectionLostAt: null,
dismissedConnectionWarning: false,
};
export const gameReducer = (state = initialState, action) => {
@@ -33,6 +34,13 @@ export const gameReducer = (state = initialState, action) => {
return {
...state,
connectionLostAt: null,
dismissedConnectionWarning: false,
};
}
if (type === dismissWarning.type) {
return {
...state,
dismissedConnectionWarning: true,
};
}
return state;
+11 -1
View File
@@ -1,4 +1,6 @@
import { Button } from 'tgui_ch/components'; // CHOMPEdit - tgui_ch
import { useDispatch } from 'common/redux';
import { dismissWarning } from './game/actions';
let url: string | null = null;
@@ -11,10 +13,11 @@ setInterval(() => {
});
}, 5000);
export const ReconnectButton = () => {
export const ReconnectButton = (props, context) => {
if (!url) {
return null;
}
const dispatch = useDispatch(context);
return (
<>
<Button
@@ -32,6 +35,13 @@ export const ReconnectButton = () => {
}}>
Relaunch game
</Button>
<Button
color="white"
onClick={() => {
dispatch(dismissWarning());
}}>
Dismiss
</Button>
</>
);
};
@@ -42,6 +42,7 @@ export const SettingsPanel = (props, context) => {
</Stack.Item>
<Stack.Item grow={1} basis={0}>
{activeTab === 'general' && <SettingsGeneral />}
{activeTab === 'limits' && <MessageLimits />}
{activeTab === 'export' && <ExportTab />}
{activeTab === 'chatPage' && <ChatPageSettings />}
{activeTab === 'textHighlight' && <TextHighlightSettings />}
@@ -169,9 +170,101 @@ export const SettingsGeneral = (props, context) => {
);
};
export const MessageLimits = (props, context) => {
const dispatch = useDispatch(context);
const {
visibleMessageLimit,
persistentMessageLimit,
combineMessageLimit,
combineIntervalLimit,
} = useSelector(context, selectSettings);
return (
<Section>
<LabeledList>
<LabeledList.Item label="Amount of lines to display 500-10000 (Default: 2500)">
<NumberInput
width="5em"
step={100}
stepPixelSize={2}
minValue={500}
maxValue={10000}
value={visibleMessageLimit}
format={(value) => toFixed(value)}
onDrag={(e, value) =>
dispatch(
updateSettings({
visibleMessageLimit: value,
})
)
}
/>
</LabeledList.Item>
<LabeledList.Item label="Amount of visually persistent lines 500-10000 (Default: 1000)">
<NumberInput
width="5em"
step={100}
stepPixelSize={2}
minValue={500}
maxValue={10000}
value={persistentMessageLimit}
format={(value) => toFixed(value)}
onDrag={(e, value) =>
dispatch(
updateSettings({
persistentMessageLimit: value,
})
)
}
/>
</LabeledList.Item>
<LabeledList.Item label="Amount of different lines in between to combine 0-10 (Default: 5)">
<NumberInput
width="5em"
step={1}
stepPixelSize={10}
minValue={0}
maxValue={10}
value={combineMessageLimit}
format={(value) => toFixed(value)}
onDrag={(e, value) =>
dispatch(
updateSettings({
combineMessageLimit: value,
})
)
}
/>
</LabeledList.Item>
<LabeledList.Item label="Time to combine messages 0-10 (Default: 5 Seconds)">
<NumberInput
width="5em"
step={1}
stepPixelSize={10}
minValue={0}
maxValue={10}
value={combineIntervalLimit}
unit="s"
format={(value) => toFixed(value)}
onDrag={(e, value) =>
dispatch(
updateSettings({
combineIntervalLimit: value,
})
)
}
/>
</LabeledList.Item>
</LabeledList>
</Section>
);
};
export const ExportTab = (props, context) => {
const dispatch = useDispatch(context);
const { logRetainDays, logLineCount } = useSelector(context, selectSettings);
const { logRetainDays, logLineCount, totalStoredMessages } = useSelector(
context,
selectSettings
);
const [purgeConfirm, setPurgeConfirm] = useLocalState(
context,
'purgeConfirm',
@@ -197,11 +290,15 @@ export const ExportTab = (props, context) => {
</LabeledList.Item>
*/}
<LabeledList.Item label="Amount of lines to export (-1 = inf.)">
<Input
<NumberInput
width="5em"
monospace
step={100}
stepPixelSize={2}
minValue={-1}
maxValue={50000}
value={logLineCount}
onInput={(e, value) =>
format={(value) => toFixed(value)}
onDrag={(e, value) =>
dispatch(
updateSettings({
logLineCount: value,
@@ -210,6 +307,9 @@ export const ExportTab = (props, context) => {
}
/>
</LabeledList.Item>
<LabeledList.Item label="Totally stored messages">
<Box>{totalStoredMessages}</Box>
</LabeledList.Item>
</LabeledList>
<Divider />
<Button icon="save" onClick={() => dispatch(saveChatToDisk())}>
@@ -9,6 +9,10 @@ export const SETTINGS_TABS = [
id: 'general',
name: 'General',
},
{
id: 'limits',
name: 'Visual Limits',
},
{
id: 'export',
name: 'Export',
@@ -30,6 +30,11 @@ const initialState = {
activeTab: SETTINGS_TABS[0].id,
},
showReconnectWarning: true,
visibleMessageLimit: 2500,
persistentMessageLimit: 1000,
combineMessageLimit: 5,
combineIntervalLimit: 5,
totalStoredMessages: 0,
logRetainDays: -1,
logLineCount: -1,
};
@@ -369,6 +369,7 @@ img.icon.bigicon {
.say,
.emote,
.emotesubtle,
.npcemote,
.infoplain,
.oocplain,
@@ -387,6 +387,7 @@ img.icon.bigicon {
.say,
.emote,
.emotesubtle,
.npcemote,
.infoplain,
.oocplain,
@@ -369,6 +369,7 @@ img.icon.bigicon {
.say,
.emote,
.emotesubtle,
.npcemote,
.infoplain,
.oocplain,
@@ -387,6 +387,7 @@ img.icon.bigicon {
.say,
.emote,
.emotesubtle,
.npcemote,
.infoplain,
.oocplain,
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+1
View File
@@ -4297,6 +4297,7 @@
#include "code\modules\telesci\telesci_computer.dm"
#include "code\modules\tension\tension.dm"
#include "code\modules\tgchat\_legacy.dm"
#include "code\modules\tgchat\chat_verbs.dm"
#include "code\modules\tgchat\message.dm"
#include "code\modules\tgchat\to_chat.dm"
#include "code\modules\tgs\includes.dm"