123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684 |
- /*
- * Copyright (c) 2006-2017 DMDirc Developers
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
- * documentation files (the "Software"), to deal in the Software without restriction, including without limitation the
- * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
- * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS
- * OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
- * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-
- package com.dmdirc.addons.logging;
-
- import com.dmdirc.Query;
- import com.dmdirc.commandline.CommandLineOptionsModule.Directory;
- import com.dmdirc.config.GlobalConfig;
- import com.dmdirc.config.prefs.PluginPreferencesCategory;
- import com.dmdirc.config.prefs.PreferencesCategory;
- import com.dmdirc.config.prefs.PreferencesDialogModel;
- import com.dmdirc.config.prefs.PreferencesSetting;
- import com.dmdirc.config.prefs.PreferencesType;
- import com.dmdirc.events.BaseChannelActionEvent;
- import com.dmdirc.events.BaseChannelMessageEvent;
- import com.dmdirc.events.BaseQueryActionEvent;
- import com.dmdirc.events.BaseQueryMessageEvent;
- import com.dmdirc.events.ChannelClosedEvent;
- import com.dmdirc.events.ChannelGotTopicEvent;
- import com.dmdirc.events.ChannelJoinEvent;
- import com.dmdirc.events.ChannelKickEvent;
- import com.dmdirc.events.ChannelModeChangeEvent;
- import com.dmdirc.events.ChannelNickChangeEvent;
- import com.dmdirc.events.ChannelOpenedEvent;
- import com.dmdirc.events.ChannelPartEvent;
- import com.dmdirc.events.ChannelQuitEvent;
- import com.dmdirc.events.ChannelTopicChangeEvent;
- import com.dmdirc.events.ClientPrefsOpenedEvent;
- import com.dmdirc.events.QueryClosedEvent;
- import com.dmdirc.events.QueryOpenedEvent;
- import com.dmdirc.events.eventbus.EventBus;
- import com.dmdirc.interfaces.GroupChat;
- import com.dmdirc.interfaces.GroupChatUser;
- import com.dmdirc.interfaces.PrivateChat;
- import com.dmdirc.interfaces.User;
- import com.dmdirc.interfaces.WindowModel;
- import com.dmdirc.config.provider.AggregateConfigProvider;
- import com.dmdirc.config.provider.ConfigChangeListener;
- import com.dmdirc.plugins.PluginDomain;
- import com.dmdirc.plugins.PluginInfo;
- import com.dmdirc.ui.WindowManager;
- import com.dmdirc.ui.messages.BackBufferFactory;
- import com.dmdirc.ui.messages.IRCControlCodes;
- import com.dmdirc.ui.messages.StyledMessageUtils;
- import com.dmdirc.util.io.ReverseFileReader;
- import com.dmdirc.util.io.StreamUtils;
- import java.awt.Color;
- import java.io.BufferedWriter;
- import java.io.File;
- import java.io.FileWriter;
- import java.io.IOException;
- import java.nio.file.Files;
- import java.nio.file.Path;
- import java.nio.file.Paths;
- import java.text.DateFormat;
- import java.text.SimpleDateFormat;
- import java.time.format.DateTimeFormatter;
- import java.util.ArrayList;
- import java.util.Collection;
- import java.util.Collections;
- import java.util.Date;
- import java.util.HashMap;
- import java.util.Map;
- import java.util.Stack;
- import java.util.Timer;
- import java.util.TimerTask;
- import javax.inject.Inject;
- import javax.inject.Provider;
- import javax.inject.Singleton;
- import net.engio.mbassy.listener.Handler;
- import org.slf4j.Logger;
- import org.slf4j.LoggerFactory;
-
- import static com.dmdirc.util.LogUtils.USER_ERROR;
-
- /**
- * Manages logging activities.
- */
- @Singleton
- public class LoggingManager implements ConfigChangeListener {
-
- private static final Logger LOG = LoggerFactory.getLogger(LoggingManager.class);
- /** Date format used for "File Opened At" log. */
- private static final DateFormat OPENED_AT_FORMAT = new SimpleDateFormat(
- "EEEE MMMM dd, yyyy - HH:mm:ss");
- /** Object for synchronising access to the date forma.t */
- private static final Object FORMAT_LOCK = new Object();
- private static final DateFormat LOG_FORMAT = new SimpleDateFormat("[dd/MM/yyyy HH:mm:ss]");
- /** This plugin's plugin info. */
- private final String domain;
- private final PluginInfo pluginInfo;
- /** Global config. */
- private final AggregateConfigProvider config;
- /** The manager to add history windows to. */
- private final WindowManager windowManager;
- /** Map of open files. */
- private final Map<String, OpenFile> openFiles = Collections.synchronizedMap(new HashMap<>());
- private final EventBus eventBus;
- private final Provider<String> directoryProvider;
- private final BackBufferFactory backBufferFactory;
- private final LogFileLocator locator;
- private final StyledMessageUtils styleUtils;
- /** Timer used to close idle files. */
- private Timer idleFileTimer;
- /** Cached boolean settings. */
- private boolean addtime;
- private boolean stripcodes;
- private boolean channelmodeprefix;
- private boolean autobackbuffer;
- private String colour;
- /** Cached int settings. */
- private int historyLines;
- private int backbufferLines;
-
- @Inject
- public LoggingManager(
- @PluginDomain(LoggingPlugin.class) final String domain,
- @PluginDomain(LoggingPlugin.class) final PluginInfo pluginInfo,
- @GlobalConfig final AggregateConfigProvider globalConfig,
- final WindowManager windowManager, final EventBus eventBus,
- @Directory(LoggingModule.LOGS_DIRECTORY) final Provider<String> directoryProvider,
- final BackBufferFactory backBufferFactory,
- final LogFileLocator locator,
- final StyledMessageUtils styleUtils) {
- this.domain = domain;
- this.pluginInfo = pluginInfo;
- this.config = globalConfig;
- this.windowManager = windowManager;
- this.eventBus = eventBus;
- this.directoryProvider = directoryProvider;
- this.backBufferFactory = backBufferFactory;
- this.locator = locator;
- this.styleUtils = styleUtils;
- }
-
- public void load() {
- setCachedSettings();
-
- final File dir = new File(directoryProvider.get());
- if (dir.exists()) {
- if (!dir.isDirectory()) {
- LOG.info(USER_ERROR, "Unable to create logging dir (file exists instead)");
- }
- } else {
- if (!dir.mkdirs()) {
- LOG.info(USER_ERROR, "Unable to create logging dir");
- }
- }
-
- config.addChangeListener(domain, this);
-
- // Close idle files every hour.
- idleFileTimer = new Timer("LoggingPlugin Timer");
- idleFileTimer.schedule(new TimerTask() {
-
- @Override
- public void run() {
- timerTask();
- }
- }, 3600000);
-
- eventBus.subscribe(this);
- }
-
- public void unload() {
- if (idleFileTimer != null) {
- idleFileTimer.cancel();
- idleFileTimer.purge();
- }
-
- synchronized (openFiles) {
- for (OpenFile file : openFiles.values()) {
- StreamUtils.close(file.writer);
- }
- openFiles.clear();
- }
-
- eventBus.unsubscribe(this);
- }
-
- /**
- * What to do every hour when the timer fires.
- */
- protected void timerTask() {
- // Oldest time to allow
- final long oldestTime = System.currentTimeMillis() - 3480000;
-
- synchronized (openFiles) {
- final Collection<String> old = new ArrayList<>(openFiles.size());
- openFiles.entrySet().stream()
- .filter(entry -> entry.getValue().lastUsedTime < oldestTime)
- .forEach(entry -> {
- StreamUtils.close(entry.getValue().writer);
- old.add(entry.getKey());
- });
-
- openFiles.keySet().removeAll(old);
- }
- }
-
- @Handler
- public void handleQueryOpened(final QueryOpenedEvent event) {
- final String filename = locator.getLogFile(event.getQuery().getUser());
- if (autobackbuffer) {
- showBackBuffer(event.getQuery().getWindowModel(), filename);
- }
-
- synchronized (FORMAT_LOCK) {
- appendLine(filename, "*** Query opened at: %s", OPENED_AT_FORMAT.format(new Date()));
- appendLine(filename, "*** Query with User: %s", event.getQuery().getUser().getNickname()
- + '!' + event.getQuery().getUser().getUsername().orElse("")
- + '@' + event.getQuery().getUser().getHostname().orElse(""));
- appendLine(filename, "");
- }
- }
-
- @Handler
- public void handleQueryClosed(final QueryClosedEvent event) {
- final String filename = locator.getLogFile(event.getQuery().getUser());
-
- synchronized (FORMAT_LOCK) {
- appendLine(filename, "*** Query closed at: %s", OPENED_AT_FORMAT.format(new Date()));
- }
-
- if (openFiles.containsKey(filename)) {
- StreamUtils.close(openFiles.get(filename).writer);
- openFiles.remove(filename);
- }
- }
-
- @Handler
- public void handleQueryActions(final BaseQueryActionEvent event) {
- final User user = event.getQuery().getUser();
- final String filename = locator.getLogFile(user);
- appendLine(filename, "* %s %s", user.getNickname(), event.getMessage());
- }
-
- @Handler
- public void handleQueryMessages(final BaseQueryMessageEvent event) {
- final User user = event.getQuery().getUser();
- final String filename = locator.getLogFile(user);
- appendLine(filename, "<%s> %s", user.getNickname(), event.getMessage());
- }
-
- @Handler
- public void handleChannelMessage(final BaseChannelMessageEvent event) {
- final String filename = locator.getLogFile(event.getChannel());
- appendLine(filename, "<%s> %s", getDisplayName(event.getClient()), event.getMessage());
- }
-
- @Handler
- public void handleChannelAction(final BaseChannelActionEvent event) {
- final String filename = locator.getLogFile(event.getChannel());
- appendLine(filename, "* %s %s", getDisplayName(event.getClient()), event.getMessage());
- }
-
- @Handler
- public void handleChannelGotTopic(final ChannelGotTopicEvent event) {
- final String filename = locator.getLogFile(event.getChannel());
- appendLine(filename, "*** Topic is: %s", event.getTopic().getTopic());
- appendLine(filename, "*** Set at: %s on %s by %s",
- event.getTopic().getDate().format(DateTimeFormatter.ofPattern("HH:mm:ss")),
- event.getTopic().getDate().format(DateTimeFormatter.ofPattern("dd/MM/yyyy")),
- event.getTopic().getClient()
- .map(GroupChatUser::getNickname).orElse("Unknown"));
- }
-
- @Handler
- public void handleChannelTopicChange(final ChannelTopicChangeEvent event) {
- final String filename = locator.getLogFile(event.getChannel());
- appendLine(filename, "*** %s Changed the topic to: %s",
- event.getTopic().getClient().map(this::getDisplayName).orElse(""), event.getTopic());
- }
-
- @Handler
- public void handleChannelJoin(final ChannelJoinEvent event) {
- final String filename = locator.getLogFile(event.getChannel());
- final GroupChatUser channelClient = event.getClient();
- appendLine(filename, "*** %s (%s) joined the channel", getDisplayName(channelClient),
- channelClient.getNickname());
- }
-
- @Handler
- public void handleChannelPart(final ChannelPartEvent event) {
- final String filename = locator.getLogFile(event.getChannel());
- final String message = event.getMessage();
- final GroupChatUser channelClient = event.getClient();
- if (message.isEmpty()) {
- appendLine(filename, "*** %s (%s) left the channel", getDisplayName(channelClient),
- channelClient.getNickname());
- } else {
- appendLine(filename, "*** %s (%s) left the channel (%s)",
- getDisplayName(channelClient), channelClient.getNickname(), message);
- }
- }
-
- @Handler
- public void handleChannelQuit(final ChannelQuitEvent event) {
- final String filename = locator.getLogFile(event.getChannel());
- final String reason = event.getMessage();
- final GroupChatUser channelClient = event.getClient();
- if (reason.isEmpty()) {
- appendLine(filename, "*** %s (%s) Quit IRC",
- getDisplayName(channelClient), channelClient.getNickname());
- } else {
- appendLine(filename, "*** %s (%s) Quit IRC (%s)",
- getDisplayName(channelClient), channelClient.getNickname(), reason);
- }
- }
-
- @Handler
- public void handleChannelKick(final ChannelKickEvent event) {
- final GroupChatUser victim = event.getVictim();
- final GroupChatUser perpetrator = event.getClient();
- final String reason = event.getReason();
- final String filename = locator.getLogFile(event.getChannel());
-
- if (reason.isEmpty()) {
- appendLine(filename, "*** %s was kicked by %s",
- getDisplayName(victim), getDisplayName(perpetrator));
- } else {
- appendLine(filename, "*** %s was kicked by %s (%s)",
- getDisplayName(victim), getDisplayName(perpetrator), reason);
- }
- }
-
- @Handler
- public void handleNickChange(final ChannelNickChangeEvent event) {
- final String filename = locator.getLogFile(event.getChannel());
- appendLine(filename, "*** %s is now %s", getDisplayName(event.getClient(),
- event.getOldNick()), getDisplayName(event.getClient()));
- }
-
- @Handler
- public void handleModeChange(final ChannelModeChangeEvent event) {
- final String filename = locator.getLogFile(event.getChannel());
- if (event.getClient().getNickname().isEmpty()) {
- appendLine(filename, "*** Channel modes are: %s", event.getModes());
- } else {
- appendLine(filename, "*** %s set modes: %s",
- getDisplayName(event.getClient()), event.getModes());
- }
- }
-
- @Override
- public void configChanged(final String domain, final String key) {
- setCachedSettings();
- }
-
- @Handler
- public void handleChannelOpened(final ChannelOpenedEvent event) {
- final String filename = locator.getLogFile(event.getChannel());
- System.out.println("\tChannel opened filename: " + filename);
-
- if (autobackbuffer) {
- showBackBuffer(event.getChannel().getWindowModel(), filename);
- }
-
- synchronized (FORMAT_LOCK) {
- appendLine(filename, "*** Channel opened at: %s", OPENED_AT_FORMAT.format(new Date()));
- appendLine(filename, "");
- }
- }
-
- @Handler
- public void handleChannelClosed(final ChannelClosedEvent event) {
- final String filename = locator.getLogFile(event.getChannel());
-
- synchronized (FORMAT_LOCK) {
- appendLine(filename, "*** Channel closed at: %s", OPENED_AT_FORMAT.format(new Date()));
- }
-
- if (openFiles.containsKey(filename)) {
- StreamUtils.close(openFiles.get(filename).writer);
- openFiles.remove(filename);
- }
- }
-
- /**
- * Add a backbuffer to a frame.
- *
- * @param frame The frame to add the backbuffer lines to
- * @param filename File to get backbuffer from
- */
- protected void showBackBuffer(final WindowModel frame, final String filename) {
- if (frame == null) {
- LOG.info(USER_ERROR, "Unable to show back buffer, frame was null");
- return;
- }
-
- final Path testFile = Paths.get(filename);
- if (Files.exists(testFile)) {
- try (final ReverseFileReader file = new ReverseFileReader(testFile)) {
- // Because the file includes a newline char at the end, an empty line
- // is returned by getLines. To counter this, we call getLines(1) and do
- // nothing with the output.
- file.getLines(1);
- final Stack<String> lines = file.getLines(backbufferLines);
- while (!lines.empty()) {
- frame.getEventBus().publishAsync(new HistoricalLineRestoredEvent(frame,
- getColouredString(colour, lines.pop())));
- }
- file.close();
- frame.getEventBus().publishAsync(new HistoricalLineRestoredEvent(frame,
- getColouredString(colour, "--- End of backbuffer\n")));
- } catch (IOException | SecurityException e) {
- LOG.info(USER_ERROR, "Unable to show backbuffer (Filename: {}): {}", filename,
- e.getMessage(), e);
- }
- }
- }
-
- /**
- * Get a coloured String. If colour is invalid, IRC Colour 14 will be used.
- *
- * @param colour The colour the string should be (IRC Colour or 6-digit hex colour)
- * @param line the line to colour
- *
- * @return The given line with the appropriate irc codes appended/prepended to colour it.
- */
- protected static String getColouredString(final String colour, final String line) {
- String res = null;
- if (colour.length() < 3) {
- int num;
-
- try {
- num = Integer.parseInt(colour);
- } catch (NumberFormatException ex) {
- num = -1;
- }
-
- if (num >= 0 && num <= 15) {
- res = String.format("%c%02d%s%1$c", IRCControlCodes.COLOUR, num, line);
- }
- } else if (colour.length() == 6) {
- try {
- Color.decode('#' + colour);
- res = String.format("%c%s%s%1$c", IRCControlCodes.COLOUR_HEX, colour, line);
- } catch (NumberFormatException ex) { /* Do Nothing */ }
- }
-
- if (res == null) {
- res = String.format("%c%02d%s%1$c", IRCControlCodes.COLOUR, 14, line);
- }
- return res;
- }
-
- /**
- * Add a line to a file.
- *
- * @param filename Name of file to write to
- * @param format Format of line to add. (NewLine will be added Automatically)
- * @param args Arguments for format
- *
- * @return true on success, else false.
- */
- protected boolean appendLine(final String filename, final String format, final Object... args) {
- return appendLine(filename, String.format(format, args));
- }
-
- /**
- * Add a line to a file.
- *
- * @param filename Name of file to write to
- * @param line Line to add. (NewLine will be added Automatically)
- *
- * @return true on success, else false.
- */
- protected boolean appendLine(final String filename, final String line) {
- final StringBuilder finalLine = new StringBuilder();
-
- if (addtime) {
- final String dateString = LOG_FORMAT.format(new Date()).trim();
- finalLine.append(dateString);
- finalLine.append(' ');
- }
-
- if (stripcodes) {
- finalLine.append(styleUtils.stripControlCodes(line));
- } else {
- finalLine.append(line);
- }
-
- try {
- final BufferedWriter out;
- if (openFiles.containsKey(filename)) {
- final OpenFile of = openFiles.get(filename);
- of.lastUsedTime = System.currentTimeMillis();
- out = of.writer;
- } else {
- out = new BufferedWriter(new FileWriter(filename, true));
- openFiles.put(filename, new OpenFile(out));
- }
- out.write(finalLine.toString());
- out.newLine();
- out.flush();
- return true;
- } catch (IOException e) {
- /*
- * Do Nothing
- *
- * Makes no sense to keep adding errors to the logger when we can't write to the file,
- * as chances are it will happen on every incoming line.
- */
- }
- return false;
- }
-
- /**
- * Get name to display for channelClient (Taking into account the channelmodeprefix setting).
- *
- * @param channelClient The client to get the display name for
- *
- * @return name to display
- */
- protected String getDisplayName(final GroupChatUser channelClient) {
- return getDisplayName(channelClient, "");
- }
-
- /**
- * Get name to display for channelClient (Taking into account the channelmodeprefix setting).
- *
- * @param channelClient The client to get the display name for
- * @param overrideNick Nickname to display instead of real nickname
- *
- * @return name to display
- */
- protected String getDisplayName(final GroupChatUser channelClient, final String overrideNick) {
- if (channelClient == null) {
- return overrideNick.isEmpty() ? "Unknown Client" : overrideNick;
- } else if (overrideNick.isEmpty()) {
- return channelmodeprefix ? channelClient.getModePrefixedNickname()
- : channelClient.getNickname();
- } else {
- return channelmodeprefix ? channelClient.getImportantMode() + overrideNick :
- overrideNick;
- }
- }
-
- /**
- * Shows the history window for the specified target, if available.
- *
- * @param target The window whose history we're trying to open
- *
- * @return True if the history is available, false otherwise
- */
- protected boolean showHistory(final WindowModel target) {
- final Path log;
-
- if (target instanceof GroupChat) {
- log = Paths.get(locator.getLogFile((GroupChat)target));
- } else if (target instanceof Query) {
- log = Paths.get(locator.getLogFile(((PrivateChat) target).getUser()));
- } else {
- // Unknown component
- return false;
- }
-
-
-
- if (!Files.exists(log)) {
- // File doesn't exist
- return false;
- }
-
- windowManager.addWindow(target, new HistoryWindow("History", log, target,
- eventBus, backBufferFactory, historyLines));
-
- return true;
- }
-
- /** Updates cached settings. */
- public void setCachedSettings() {
- addtime = config.getOptionBool(domain, "general.addtime");
- stripcodes = config.getOptionBool(domain, "general.stripcodes");
- channelmodeprefix = config.getOptionBool(domain, "general.channelmodeprefix");
- autobackbuffer = config.getOptionBool(domain, "backbuffer.autobackbuffer");
- historyLines = config.getOptionInt(domain, "history.lines");
- colour = config.getOption(domain, "backbuffer.colour");
- backbufferLines = config.getOptionInt(domain, "backbuffer.lines");
- }
-
- @Handler
- public void showConfig(final ClientPrefsOpenedEvent event) {
- final PreferencesDialogModel manager = event.getModel();
- final PreferencesCategory general = new PluginPreferencesCategory(
- pluginInfo, "Logging", "General configuration for Logging plugin.");
- final PreferencesCategory backbuffer = new PluginPreferencesCategory(
- pluginInfo, "Back Buffer", "Options related to the automatic backbuffer");
- final PreferencesCategory advanced = new PluginPreferencesCategory(
- pluginInfo, "Advanced",
- "Advanced configuration for Logging plugin. You shouldn't need to edit this unless you know what you are doing.");
-
- general.addSetting(new PreferencesSetting(PreferencesType.DIRECTORY,
- pluginInfo.getDomain(), "general.directory", "Directory",
- "Directory for log files", manager.getConfigManager(),
- manager.getIdentity()));
- general.addSetting(new PreferencesSetting(PreferencesType.BOOLEAN,
- pluginInfo.getDomain(), "general.networkfolders",
- "Separate logs by network",
- "Should the files be stored in a sub-dir with the networks name?",
- manager.getConfigManager(), manager.getIdentity()));
- general.addSetting(new PreferencesSetting(PreferencesType.BOOLEAN,
- pluginInfo.getDomain(), "general.addtime", "Timestamp logs",
- "Should a timestamp be added to the log files?",
- manager.getConfigManager(), manager.getIdentity()));
- general.addSetting(new PreferencesSetting(PreferencesType.BOOLEAN,
- pluginInfo.getDomain(), "general.stripcodes", "Strip Control Codes",
- "Remove known irc control codes from lines before saving?",
- manager.getConfigManager(), manager.getIdentity()));
- general.addSetting(new PreferencesSetting(PreferencesType.BOOLEAN,
- pluginInfo.getDomain(), "general.channelmodeprefix",
- "Show channel mode prefix", "Show the @,+ etc next to nicknames",
- manager.getConfigManager(), manager.getIdentity()));
-
- backbuffer.addSetting(new PreferencesSetting(PreferencesType.BOOLEAN,
- pluginInfo.getDomain(), "backbuffer.autobackbuffer", "Automatically display",
- "Automatically display the backbuffer when a channel is joined",
- manager.getConfigManager(), manager.getIdentity()));
- backbuffer.addSetting(new PreferencesSetting(PreferencesType.COLOUR,
- pluginInfo.getDomain(), "backbuffer.colour", "Colour to use for display",
- "Colour used when displaying the backbuffer",
- manager.getConfigManager(), manager.getIdentity()));
- backbuffer.addSetting(new PreferencesSetting(PreferencesType.INTEGER,
- pluginInfo.getDomain(), "backbuffer.lines", "Number of lines to show",
- "Number of lines used when displaying backbuffer",
- manager.getConfigManager(), manager.getIdentity()));
-
- advanced.addSetting(new PreferencesSetting(PreferencesType.BOOLEAN,
- pluginInfo.getDomain(), "advanced.filenamehash", "Add Filename hash",
- "Add the MD5 hash of the channel/client name to the filename. "
- + "(This is used to allow channels with similar names "
- + "(ie a _ not a -) to be logged separately)",
- manager.getConfigManager(), manager.getIdentity()));
-
- advanced.addSetting(new PreferencesSetting(PreferencesType.BOOLEAN,
- pluginInfo.getDomain(), "advanced.usedate", "Use Date directories",
- "Should the log files be in separate directories based on the date?",
- manager.getConfigManager(), manager.getIdentity()));
- advanced.addSetting(new PreferencesSetting(PreferencesType.TEXT,
- pluginInfo.getDomain(), "advanced.usedateformat", "Archive format",
- "The String to pass to 'SimpleDateFormat' to format the "
- + "directory name(s) for archiving",
- manager.getConfigManager(), manager.getIdentity()));
-
- general.addSubCategory(backbuffer.setInline());
- general.addSubCategory(advanced.setInline());
- manager.getCategory("Plugins").addSubCategory(general.setInlineAfter());
- }
-
- /** Open File. */
- private static class OpenFile {
-
- /** Last used time. */
- public long lastUsedTime = System.currentTimeMillis();
- /** Open file's writer. */
- public final BufferedWriter writer;
-
- /**
- * Creates a new open file.
- *
- * @param writer Writer that has file open
- */
- protected OpenFile(final BufferedWriter writer) {
- this.writer = writer;
- }
-
- }
-
- }
|